如何从.ui文件中为Qt按钮添加函数? [英] How to add functions to Qt buttons from .ui file?

查看:0
本文介绍了如何从.ui文件中为Qt按钮添加函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始使用和发现PyQt5和Qt。我把它安装在一起 pip install pyqt5。然后我打开pyqt-tools附带的designer.exe并进行了设计。

之后,我使用pyuic design.ui > dialog.py将其从.ui转换为.py

当我运行app.py时,它运行得很好,用户界面也运行得很好。但现在我的问题是:我如何添加在按下按钮时调用的函数?

以下是我的app.py代码:

import sys
from PyQt5.QtWidgets import QDialog, QApplication
from dialog import Ui_Form

class AppWindow(QDialog)
        def __init__(self):
           super().__init__()
           self.ui = Ui_Form()
           self.ui.setupUi(self)
           self.show()  
                                              
app = QApplication(sys.argv)
w = AppWindow()
w.show()
sys.exit(app.exec_())

推荐答案

您的方法实际上是正确的(至少是正确的方法之一):pyuic生成的文件不应该修改,除非您真的(真的)知道您在做什么以及为什么。此外,永远不应该模仿他们的行为,因为没有理由这样做。

作为(我想说是强制性的)参考,您可以在using Designer的官方PyQt指南上阅读有关此主题的更多信息。

让我就这个主题做一个重要的前提。

您所做的被称为单继承方法,这意味着您正在创建一个仅从您正在使用的QWidget子类(在本例中为QDialog)继承的子类,并使用被称为窗体类的方法在其之上构建UI。Form类是一个标准的object类型,它负责在调用其setupUi函数时在主子类实例之上创建所有子窗口小部件。
结果是,子类实例将始终在其作用域内引用self,而其所有子实例都可以通过self.ui对象访问。

类似的(也是更常见的)方法是多重继承方法。通过这种方式,您可以从继承QWidget子类(QDialog)和UI对象。用户界面结果将是相同的,但使用self.objectName而不是self.ui.objectName可以更直接地使用小部件。

使用哪种方法取决于您的选择,请记住,只要您使用多重继承方法,setupUi可能会覆盖任何以前设置的实例属性,如果您为已有的对象名称创建新属性,则该对象将无法再(直接)访问。

最后,让我给你另一个建议:虽然不是完全错,但另一个答案中的link posted不仅给出了一个非常误导性的建议,而且甚至没有更多地挖掘它所指的上一篇文章为什么是错误的。底线是pyuic创建的文件不应该被修改(也不应该试图模仿它们的行为),原因有很多:不仅如果您需要更改您的UI,您将需要将已经修改的代码与新的代码合并(希望您没有使用pyuic覆盖它),而且这还会导致对整个对象结构的误解。


因此,在您的情况下(使用单一继承方法),在Designer中创建的所有对象实际上都可以使用self.ui.objectName访问,而objectName就是在Designer的对象检查器中显示的对象。

假设您创建了一个只有一个按钮的UI,并且您想要在按下该按钮时打印一些内容。如果您没有对您的用户界面进行过多的测试和修改,则该按钮的对象名称可能是。

然后,您的代码可能如下所示:

import sys
from PyQt5.QtWidgets import QDialog, QApplication
from dialog import Ui_Form

class AppWindow(QDialog)
    def __init__(self):
        super().__init__()
        self.ui = Ui_Form()
        self.ui.setupUi(self)

        self.ui.pushButton.clicked.connect(self.buttonClicked)

    def buttonClicked(self):
        print('button clicked!')

                                              
app = QApplication(sys.argv)
w = AppWindow()
w.show()
sys.exit(app.exec_())

请注意,Qt对象名称不是唯一的。从理论上讲,您可以为多个QObject(或QWidget)设置相同的对象名称,但这样做没有任何用处。从Python的角度考虑这一点:每个变量都应该有自己的名称,如果您覆盖了已经存在的变量名称,前一个变量将变得不可访问(如果不是垃圾收集的话)。
设计师足够聪明(并不是说它需要这么多……)为了防止创建共享相同对象名称的对象,这就是为什么如果您添加另一个按钮,它将被命名为pushButton_2pushButton_3等。无论您使用的是pyuic文件还是uic.loadUi(),通过为所有对象名称创建唯一的实例属性,PyQt将从中受益。

为完整起见,以下是多重继承方法在执行上述示例时的外观:


import sys
from PyQt5.QtWidgets import QDialog, QApplication
from dialog import Ui_Form

class AppWindow(QDialog, Ui_Form)
    def __init__(self):
        super().__init__()
        self.setupUi(self)

        self.pushButton.clicked.connect(self.buttonClicked)

    def buttonClicked(self):
        print('button clicked!')

                                              
app = QApplication(sys.argv)
w = AppWindow()
w.show()
sys.exit(app.exec_())

根据上面的解释,考虑属性名称问题:如果在调用self.setupUi之前创建了一个名为self.pushButton的属性,那么在该调用之后self.pushButton将是对按钮的引用,之前设置的值将丢失;如果您在调用self.setupUi之后创建了一个名为self.pushButton的新属性,您将无法再访问QPushButton实例。


现在,虽然在正常使用时它们的行为通常是相同的,但使用pyuic生成的文件或uic.loadUiType()和更直接的uic.loadUi之间存在微小但仍然重要的差异,不幸的是,这些差异没有正式记录(坦率地说,我不记得所有这些差异)。

eyllanesc以前曾在问题Size of verticalLayout is different in Qt Designer and PyQt program中报告过一个示例。

考虑这些是非常具体的异常(甚至可能在未来的PyQt版本中解决,特别是现在Qt6即将发布),并且它们通常不会对标准编程造成重大问题。

最后(终于!),虽然设计师通常很聪明,但也不是很完美。例如,在技术上不重要的&q;对象作为Q操作分隔符被视为&q;匿名&q;,而Designer甚至不应用它们的对象名称:如果您向菜单添加一个分隔符,即使您主动命名它,也无法直接访问它。

这篇关于如何从.ui文件中为Qt按钮添加函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆