【问题标题】:Two different syntax for the GUI -> Different behavioursGUI 的两种不同语法 -> 不同的行为
【发布时间】:2017-10-25 16:03:39
【问题描述】:

我正在研究 PyQt,但我绝对不清楚。 假设我想创建一个带有按钮的 GUI。 网上很多例子都有这种形式:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets

class Example(QtWidgets.QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):      

        self.setGeometry(300, 300, 200, 140)
        self.setWindowTitle('Dialog')
        self.aaa = QtWidgets.QPushButton(self)
        self.aaa.setGeometry(QtCore.QRect(40, 40, 113, 32))
        self.aaa.setObjectName("aaa")
        self.aaa.setText( "PushButton")
        self.show()



    def keyPressEvent(self, e):
        if e.key() == QtCore.Qt.Key_Return:
            self.close()


if __name__ == '__main__':

    app = QtWidgets.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

但是,如果我使用 Designer 创建相同的 GUI,然后通过 'pyuic5 -x test.ui -o test.py' 将其转换为 Python,我会获得稍微不同的代码:

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.setGeometry(300, 300, 200, 140)
        self.aaa = QtWidgets.QPushButton(Dialog)
        self.aaa.setGeometry(QtCore.QRect(40, 40, 113, 32))
        self.aaa.setObjectName("aaa")

        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.aaa.setText(_translate("Dialog", "PushButton"))


    def keyPressEvent(self, e):
        if e.key() == QtCore.Qt.Key_Return:
            self.close()


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Dialog = QtWidgets.QDialog()
    ui = Ui_Dialog()
    ui.setupUi(Dialog)
    Dialog.show()
    sys.exit(app.exec_())

除了调用等区别:

self.setGeometry(300, 300, 200, 140)

而不是

Dialog.setGeometry(300, 300, 200, 140)

有一些我无法理解的差异。

  • keyPressEvent 在第一个示例中有效,在第二个示例中无效
  • 如果我在第一个示例中按下“Escape”,则没有任何反应,如果我在第二个示例中按下它,应用程序将立即关闭
  • 该按钮在第二个示例中突出显示(因为它被设置为默认值,并且我找到了一种禁用它的方法),而在第一个示例中则没有

我正在寻找解释这一点的指南和教程,但我只能找到第一种语法的示例,而第二种对我来说会更好,因为我可以使用 Designer 设计 GUI,然后将其导出到 python 中以添加事件。 我的实际问题是:

  • 如何避免在第二个示例中使用退出按钮退出我的应用?
  • 如何让 keyPressEvent 在第二个示例中工作?

还有更多:

  • 我应该更喜欢第一种还是第二种语法,还是它们是等价的?
  • 有没有办法将设计器文件“.ui”导出到具有第一个示例中的语法的 python 文件?

谢谢!

【问题讨论】:

    标签: python python-3.x pyqt pyqt5 qt-designer


    【解决方案1】:

    在第二个示例中如何避免退出按钮退出我的应用?

    此按钮默认激活,因为在第二个示例中,您使用具有此默认行为的 QDialog 小部件,因为它们用于创建用户必须选择选项的对话框,而不是第一个示例使用 @ 987654324@是最基本的小部件。

    解决方案:作为 Widget 的模板,而不是一些没有按钮的对话框、底部按钮的对话框或右侧按钮的对话框。

    如何让 keyPressEvent 在第二个示例中工作?

    Qt Designer 创建设计类,不创建小部件,即创建填充小部件的类在第一个代码的主体中观察到,并且只有小部件具有事件keyPressEvent。解决方法很简单,你必须创建一个继承自Dialog的类,并用Qt Designer提供的类来实现widget的填充。

    class Dialog(QtWidgets.QDialog, Ui_Dialog):
        def __init__(self, *args, **kwargs):
            QtWidgets.QDialog.__init__(self, *args, **kwargs)
            self.setupUi(self)
    
        def keyPressEvent(self, e):
            if e.key() == QtCore.Qt.Key_Return:
                self.close()
    
    if __name__ == '__main__':
    
        app = QtWidgets.QApplication(sys.argv)
        w = Dialog()
        w.show()
        sys.exit(app.exec_())
    

    注意:

    以下架构显示了您在 Qt 设计器中使用的模板以及您必须继承的类:

    +-----------------------------+--------------+
    | Template                    | Widget Class |
    +-----------------------------+--------------+
    | Dialog with Buttons Bottom  | QDialog      |  
    | Dialog with Buttons Right   | QDialog      |
    | Dialog without Buttons      | QDialog      |
    | MainWindow                  | QMainWindow  |
    | Widget                      | QWidget      | 
    +-----------------------------+--------------+
    

    一般你必须使用以下方案:

    class Some_Name(Widget_Class, Template):
        def __init__(self, *args, **kwargs):
            Widget_Class.__init__(self, *args, **kwargs)
            self.setupUi(self)
    

    有关更多信息,请查看以下内容:

    【讨论】:

    • 谢谢您,您的解释非常清楚!我还将浏览您链接的文档,以便更好地了解设计师的情况!再次感谢:D
    • @Fraccalo 如果我的回答对您有帮助,请不要忘记标记为正确,如果您不知道该怎么做,请查看以下链接:stackoverflow.com/tour
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-22
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-08
    相关资源
    最近更新 更多