-
-
Notifications
You must be signed in to change notification settings - Fork 153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make sure loadUi is available #27
Conversation
@Nodd, could you review this one please? |
@astrofrog I disabled the complaint on non pythonic names (which is not good advice when working with Qt) But the other suggestions are valid:
|
@goanpeca @ccordoba12 - I've added fixes, but I think in this case the coding guidelines are being over-strict. The class that was missing a docstring was private (starting with |
@astrofrog yes probably, but even if private a docstring is always a good idea :-p. For the test one, yes I agree it is kinda too much, but thanks for including the changes 👍 |
e5cbe60
to
e354091
Compare
|
||
__all__ = ['loadUi'] | ||
|
||
if os.environ[QT_API] in PYQT5_API: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use the constants here: PYQT5
and so on
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
The logic in @astrofrog Regarding PySide, has any other project tried to load the custom classes from the xml directly ?
Can it be useful with a newer version of PySide ? |
# TypeError, if customWidgets is None | ||
try: | ||
widget = self.customWidgets[class_name](parent) | ||
except (TypeError, KeyError): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If self.customWidgets
is set to an empty dict if None (in the constructor), you would only catch KeyError
here. It would be easier to understand.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
Yes but we'd still need to get the custom widgets from the XML, which I think should be reasonably easy. However, I can indeed do it in a separate PR. |
@goanpeca Can you disable "Avoid using "non-Pythonic" variable names" in QuantifiedCode, please ? |
Please remove these lines as part of this PR: https://github.com/spyder-ide/qtpy/blob/master/qtpy/__init__.py#L83 https://github.com/spyder-ide/qtpy/blob/master/qtpy/__init__.py#L103 |
Yep, please leave it for another PR. |
@ccordoba12 - done! |
@Nodd, please merge this one when you consider is ready. |
|
||
class _QComboBoxSubclass(QComboBox): | ||
""" | ||
This is a private class that is used only for testing purposes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's only needed for testing, the class can be defined in test_uic.py
, to leave uic.py
clean.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue is that it needs to be part of an importable module. I could create a fake module for the duration of the test though, so I can investigate that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test file itself is importable, isn't it sufficient ?
Otherwise I think that having a separate file in the test directory containing the class is fine. Your workaround works but seems needlessly complex to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried having a file in the tests
directory, but this causes issues in Python 2, because it seems that when I adjust sys.path
, the class I import from the tests appears to be different from the one that PyQt4/5 imports. I tried working around that, but in the end, the solution in this PR is the cleanest (even though it may look complex).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By the way, the reason I have to mess with sys.path
and why this is complicated is because the tests need to also be runnable from outside the tests
directory, so I want to be able to do py.test tests/
for instance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's an example of the type of error I get if I try the approach you are suggesting:
> assert isinstance(ui.comboBox, _QComboBoxSubclass)
E assert isinstance(<test_uic._QComboBoxSubclass object at 0x11882f5e8>, _QComboBoxSubclass)
E + where <test_uic._QComboBoxSubclass object at 0x11882f5e8> = <PyQt5.QtWidgets.QWidget object at 0x11882de58>.comboBox
somehow it seems to think there are two different _QComboBoxSubclass
classes.
Sorry for the last-minute nitpick, otherwise it's ready to go ! |
@Nodd - I think this is good to go - I know the solution here seems a little strange, but see my replies to your comments above: I can't figure out a way to get this to work if the subclass lives in the test file. |
It's OK, there are problems in python if the same module is imported from 2 different paths. Thank you for your work ! |
Glue makes use of loadUi extensively, and there are a number of available patches going around to provide this in PySide. This PR adds such a patch (adapted from qt-helpers, which itself came from a previous solution).
This works fine, but one thing that all solutions seem to require is that for PySide, custom widgets need to be explicitly specified. However, this is not ideal because it provides an API that is not consistent with PyQt4/5 (where the custom widgets are auto-loaded).
One solution would be to parse the XML ourselves and load the custom widgets specified in the ui files (since the ui files provide the path to import the class). I can implement this, but I wanted to check first whether there are any objections to this?
As for #25, I included copies of the licenses for the adapted code, but there might be a better way to do this (for example we could include this in LICENSE, or have a separate file describing where various parts of the code were taken from and what their licenses were?)
Closes #16
cc @Nodd