Correct way to address Pyside Qt widgets from a .ui file via Python
我已经使用Qt Designer创建了一个GUI,并通过以下方式访问了它
1 2 3 4 5 6 7 8 9 10 11 12 | 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"已经包含在UI中创建的小部件" QPushButton1"," QTextBrowser1",但是不应由requesive findChildren()方法访问吗?
什么是访问.ui文件小部件的优雅方法?
参考文献:
找到正确的实例,
加载.ui文件
由于Qt Designer中的窗口小部件名称必须唯一,因此层次结构(至少用于获取窗口小部件的引用)是平坦的(没有冲突的风险),因此最好的方法是通过以下方式访问它们:
1 2 3 | loader = QtUiTools.QUiLoader() ui = loader.load('filename.ui', parent) my_widget = ui.my_widget_name |
这将在Qt Designer中的变量
我要说的是,以上是访问在加载.ui文件时创建的小部件的最pythonic方式。
在运行时加载UI有两个缺点:
- 每次运行程序时的开销(实际上,每次使用加载程序时)
-
缺少对代码完成和检查的支持,因为在加载uifile之前,IDE不知道
ui 后面的代码。
假设您使用的是PySide的现代版本" Qt for Python",则另一种方法是将.ui文件"编译"为Python类(请参阅docs)。为此,保存
1 | pyside2-uic filename.ui -o ui_mainwindow.py |
在虚拟环境中(如果有)。新类将称为Ui_MainWindow。假设您的UI中有一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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_()) |
笔记:
- 每次更改.ui文件后,都应调用pyside2-uic。与OP相比,这是此方法的缺点。这也意味着您应该对UI的.ui和.py文件进行版本控制,或者在部署期间以某种方式调用uic。
- 最大的优势在于,像PyCharm这样的IDE可以访问所有小部件方法和属性,以进行自动补全和代码检查。
- 到目前为止,pyside2-uic会创建不符合PEP8的代码。但是,只要给窗口小部件提供符合PEP8的名称,您自己的代码就可以了。