-
Notifications
You must be signed in to change notification settings - Fork 253
Add support for additional arguments to load_ui #80
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
Comments
Thanks @bpabel.
Would it be possible to link to this discussion?
Excellent, would you happen to know whether the same implementation works for PySide2? If you put a pull-request in, we could have it run through tests on each platform, Python version and Qt distribution. That should get the conversation started. As I'm not a user of loadUi myself, it would also be lovely to have one or more usage examples so that we implement it in a way that makes sense to you. |
This was from the closed 3DPRO mailing list. I asked Abel to post an issue :)
I've made a gist where this works in PySide2: I think Abel's request makes a lot of sense. I omitted additional arguments to the |
Would it be possible to post a minimal example |
I could do a PR, but I won't have time for it until mid August 😢 as I'm on vacation with my family 😄 However, here's an example UI file which we could use for this example. Today, we can access the widgets from the ui file like this: import sys
from Qt import QtWidgets
from Qt import load_ui
class Hello(QtWidgets.QWidget):
def __init__(self):
super(Hello, self).__init__()
self.ui = load_ui('main_window.ui')
print(self.ui.boilerPushButton) # a pushButton widget from main_window.ui
app = QtWidgets.QApplication(sys.argv)
window = Hello()
window.ui.show()
sys.exit(app.exec_()) However, we can't load the UI widgets directly into Here's a full example of me loading two UIs with the current behaviour of This is what we want to be able to do with an optional second argument to class Hello(QtWidgets.QWidget):
def __init__(self):
super(Hello, self).__init__()
self.ui = load_ui('main_window.ui', self) # Load widgets into self
print(self.boilerPushButton) # the button is now available in self Of course, you could also load widgets into something else than just @mottosso if you like, we can assign this to me, but I won't have time for it until a couple of weeks away. It would basically entail updating |
Sorry, I edited my prevous post a lot to clarify things a bit with better examples. Please re-read it if you already read it. |
If we were to write tests for this, we'd need to store a .ui file in the repository. How do you feel about that, @mottosso ? We could create a main_window.ui file in a |
We could, but I'd rather keep it contained in the test module. If you hand me a .ui snippet, I can show you how I mean. |
Will this do? <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>125</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui> |
Here's what I had in mind. def test_pyside_load_ui():
"""load_ui works well"""
ui = """\
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>125</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>"""
with tempfile.NamedTemporaryFile(suffix=".ui") as f:
f.write(ui)
f.seek(0)
with pyside():
import Qt
widget = Qt.load_ui(f.name) Ideally then, the .ui file would only contain parts we are actually testing. In this case, perhaps QStatusBar and explicit widths are less important in the interest of readability. |
Ah, yes. That's an excellent idea. |
It might not seem like a big deal today. From experience with maintaining external files with tests, I find that this works fine initially, but then as the project is updated, tests change, and the external files will need to branch out to cover both in order to be backwards compatible. With this approach, even though it makes each test bigger and more repetitive, tests and data change together and should be easier to maintain long-term. |
Yep. Agreed. |
Hm, so I'm wondering about one thing. It looks like we could add a custom class to the Right now, I'm just putting the class definition in both these functions. Any idea on how we could structure this more nicely? |
Never mind, I think I found a solution. |
@fredrikaverpil If you can, please post an example or two of the intended usage before looking at implementing this. What I'm looking for is to have tests in place before the implementation starts. TDD style. |
Yes, I'm doing the tests now. But as I had to rebuild the docker container I now am having issues with nosetests complaining about not being able to connect to an X server:
Even if I remove my load_ui test, I get the X server error. It seems nosetests broke after I re-built the container from scratch. There are no detailed error messages since nosetests errors out with this X server notice before it can get there. Do you see this on your end too if you rebuild your container? Here's my test: def test_pyside_load_ui():
"""load_ui works well"""
ui = """\
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>125</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>"""
with tempfile.NamedTemporaryFile(suffix=".ui") as f:
f.write(ui)
f.seek(0)
with pyside():
from Qt import QtWidgets, load_ui
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self, parent)
load_ui(f.name, self)
assert self.pushButton
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
# window.show()
# app.exec_() I intend to remove QStatusBar, QMenuBar etc as soon as I get this example working. |
See #81 |
Per the python mailing list discussion, add support for the 2nd argument to uic.loadUi
Here is an example using PyQt4
http://nullege.com/codes/search/PyQt4.uic.loadUi
Here is an example of an implementation for PySide that accepts the same arguments
https://gist.github.com/cpbotha/1b42a20c8f3eb9bb7cb8
The text was updated successfully, but these errors were encountered: