通过Python从.ui文件中解决Pyside Qt小部件的正确方法

问题描述 投票:4回答:2

我用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”,但是不应该通过recoursive findChildren()方法访问它们?

访问.ui文件小部件的优雅方法是什么?

参考文献:Find correct instanceLoad .ui file

python qt pyside
2个回答
9
投票

由于Qt Designer中的窗口小部件名称必须是唯一的,因此层次结构(至少用于获取对窗口小部件的引用)是扁平的(没有冲突风险),因此最好的方法是通过以下方式访问它们:

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

这将在Qt Designer中的变量my_widget中引用名为“my_widget_name”的小部件。

我会说上面是访问加载.ui文件时创建的小部件的最pythonic方式。


0
投票

在运行时加载UI有两个缺点:

  • 每次运行程序时的开销(实际上,每次使用加载程序时)
  • 缺乏对代码完成和检查的支持,因为IDE在加载uifile之前不知道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_())

笔记:

  • 每次更改.ui文件后都应调用pyside2-uic。与OP相比,这是该方法的缺点。它还意味着您应该为您的UI版本控制.ui和.py文件,或者在部署期间以某种方式调用uic。
  • 最大的优点是像PyCharm这样的IDE可以访问所有小部件方法和属性,以进行自动完成和代码检查。
  • 截至今天,pyside2-uic创建了非PEP8兼容代码。但是,只要您为小部件提供符合PEP8的名称,您自己的代码就可以了。
© www.soinside.com 2019 - 2024. All rights reserved.