Correct way to address Pyside Qt widgets from a .ui file via Python

老子叫甜甜 提交于 2019-12-07 11:36:54

问题


I have created a GUI with Qt Designer and accessed it via

def loadUiWidget(uifilename, parent=None):
    loader = QtUiTools.QUiLoader()
    uifile = QtCore.QFile(uifilename)
    uifile.open(QtCore.QFile.ReadOnly)
    ui = loader.load(uifile, parent)
    uifile.close()
    return ui

MainWindow = loadUiWidget("form.ui")
MainWindow.show()
children = MainWindow.children()
button1 = MainWindow.QPushButton1

"children" does already contain the widgets "QPushButton1", "QTextBrowser1" created in the UI but shouldn't the be accessed by the recoursive findChildren() method?

What is an elegant way to access the widgets of the .ui File?

References: Find correct instance, Load .ui file


回答1:


Since widget names in Qt Designer must be unique, the hierarchy (at least for getting references to the widgets) is flattened (with no risk of conflict), and so the best way is just to access them via:

loader = QtUiTools.QUiLoader()
ui = loader.load('filename.ui', parent)
my_widget = ui.my_widget_name

This would place a reference to the widget called 'my_widget_name' in Qt Designer in the variable my_widget.

I would say the above is the most pythonic way of accessing the widgets created when you load the .ui file.




回答2:


There are two disadvantages of loading UI at run time:

  • overhead each time the program is run (actually, each time the loader is used)
  • lack of support of code completion and checking, since IDE doesn't know the code behind ui until the uifile has been loaded.

An alternative, assuming you are using the modern version of PySide called "Qt for Python", is to "compile" the .ui file to a Python class (see docs). For this, after saving filename.ui, execute

pyside2-uic filename.ui -o ui_mainwindow.py

while within your virtual environment, if any. The new class will be called Ui_MainWindow. Assuming you have a text_box widget in your UI, you can now access its properties and methods. Here is a full working example:

import sys
from PySide2.QtWidgets import QApplication, QMainWindow
from ui_mainwindow import Ui_MainWindow


class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.text_box.setPlainText('test')  # here we are addressing widget


if __name__ == "__main__":
    app = QApplication(sys.argv)

    window = MainWindow()
    window.show()

    sys.exit(app.exec_())

Notes:

  • pyside2-uic should be called after every change of the .ui file. This is a disadvantage of this approach in comparison to OP. It also means that you should either version-control both .ui and .py files for your UI, or somehow call uic during deployment.
  • The big advantage is that IDE like PyCharm has access to all widget methods and properties for autocompletion and code checking.
  • As of today, pyside2-uic creates non-PEP8 compliant code. However, as long as you give your widgets PEP8-compliant names, your own code will be OK.


来源:https://stackoverflow.com/questions/20115693/correct-way-to-address-pyside-qt-widgets-from-a-ui-file-via-python

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!