GUI的两种不同语法 - >不同的行为

时间:2017-10-25 16:03:40

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

我正在研究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文件?

谢谢!

1 个答案:

答案 0 :(得分:0)

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

默认情况下,此按钮处于激活状态,因为在第二个示例中,您正在使用具有此默认行为的QDialog窗口小部件,因为它们用于创建用户必须选择选项的对话框,而第一个示例是使用QWidget这是最基本的小部件。

解决方案:用作Widget的模板,而不是没有按钮的对话框,带按钮的对话框或带按钮的对话框。

如何在第二个示例中使用keyPressEvent?

Qt Designer创建一个设计类,不创建一个小部件,即创建填充小部件的类,该小部件在第一个代码的主要部分中观察,并且只有小部件具有事件keyPressEvent。解决方案很简单,您必须创建一个继承自Dialog的类,并使用Qt Designer提供的类实现窗口小部件的填充。

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)

有关详细信息,请查看以下内容: