通过 Python 从 .ui 文件处理 Pyside Qt 小部件的正确方法
Posted
技术标签:
【中文标题】通过 Python 从 .ui 文件处理 Pyside Qt 小部件的正确方法【英文标题】:Correct way to address Pyside Qt widgets from a .ui file via Python 【发布时间】:2013-11-21 08:20:06 【问题描述】:我已经用 Qt Designer 创建了一个 GUI,并通过
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”,但不应该通过递归 findChildren() 方法访问吗?
访问 .ui 文件的小部件的优雅方式是什么?
参考资料: Find correct instance, Load .ui file
【问题讨论】:
【参考方案1】:由于 Qt Designer 中的小部件名称必须是唯一的,因此层次结构(至少用于获取对小部件的引用)是扁平的(没有冲突的风险),因此最好的方法是通过以下方式访问它们:
loader = QtUiTools.QUiLoader()
ui = loader.load('filename.ui', parent)
my_widget = ui.my_widget_name
这将在变量my_widget
中放置对Qt Designer 中名为“my_widget_name”的小部件的引用。
我会说上面是访问加载 .ui 文件时创建的小部件的最 pythonic 方式。
【讨论】:
【参考方案2】:在运行时加载 UI 有两个缺点:
程序每次运行的开销(实际上是每次使用加载器) 缺乏对代码完成和检查的支持,因为在加载 uifile 之前 IDE 不知道ui
后面的代码。
假设您使用的是名为“Qt for Python”的现代版 PySide,另一种方法是将 .ui 文件“编译”为 Python 类(请参阅docs)。为此,保存filename.ui
后,执行
pyside2-uic filename.ui -o ui_mainwindow.py
在您的虚拟环境中,如果有的话。新类将被称为 Ui_MainWindow。假设您的 UI 中有一个 text_box
小部件,您现在可以访问它的属性和方法。这是一个完整的工作示例:
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_())
注意事项:
pyside2-uic 应该在每次更改 .ui 文件后调用。与 OP 相比,这是这种方法的一个缺点。这也意味着您应该对 UI 的 .ui 和 .py 文件进行版本控制,或者在部署期间以某种方式调用 uic。 最大的优势是像 PyCharm 这样的 IDE 可以访问所有小部件方法和属性以进行自动完成和代码检查。 截至今天,pyside2-uic 创建不符合 PEP8 的代码。但是,只要您为您的小部件提供符合 PEP8 的名称,您自己的代码就可以了。【讨论】:
以上是关于通过 Python 从 .ui 文件处理 Pyside Qt 小部件的正确方法的主要内容,如果未能解决你的问题,请参考以下文章
基于python实现UI自动化3.4 JS 处理日历控件(删除 readonly 属性)
基于python实现UI自动化3.3 Selenium - JS处理浏览器滚动条