PyQt:从QDesigner和Connect按钮包装对话框

时间:2015-01-06 17:48:58

标签: python pyqt signals-slots qpushbutton pyuic

我开始学习Python和PyQt。目前我正在解决关于连接信号和插槽的一个非常基本的问题,使用从QDesigner生成的Dialog表单。 我想从QDialog连接一个按钮。代码不会生成错误。按预期显示对话框。但点击按钮没有任何反应。

或者,我尝试将代码表单Ui_Dialog直接包含在目标类Testdialog中。然后连接正常。似乎我在将属性从Ui_Dialog继承到Testdialog和/或以我想要执行Dialog的方式时出错了。

我的主程序如下:

from __future__ import unicode_literals
import sys

from PyQt4 import *
from PyQt4 import QtGui
from PyQt4.QtCore import SIGNAL, QObject

import UI_Test



class Testdialog(QtGui.QDialog, UI_Test.Ui_Dialog):
    def __init__(self,parent=None):
        super(Testdialog, self).__init__(parent)
        self.setupUi(self)
        print("Connect buttons") # gives the expected output

        self.connect(self.pushButton_Ok, SIGNAL("clicked()"), self.clickedOk)
        self.connect(self.pushButton_Cancel, SIGNAL("clicked()"), self.clickedCancel)

        # Alternativly I have tríed the following without improvement:
        # self.pushButton_Ok.clicked.connect(self.clickedOk)
        # QObject.connect(self.pushButton_Cancel, SIGNAL("clicked()"), self.clickedCancel)


    def clickedCancel(self):
        print ("Cancel")  # Question: Why is nothing happening here?


    def clickedOk(self):
        print ("Ok")       # Question: Why is nothing happening here?



if True:
    qApp = QtGui.QApplication(sys.argv)
    Dialog = QtGui.QDialog()
    u = Testdialog()
    u.setupUi(Dialog)
    Dialog.exec_()
    sys.exit(qApp.exec_())

当我点击丛林按钮时,没有任何反应。似乎连接不起作用。

我做错了什么?怎么解决它?还有什么可以改进的?

表单UI_Test.py没有什么特别之处,因为它是使用QtDesigner和pyuic自动生成的。所以基本上应该没问题(虽然我不了解代码的每一个细节)。  为了提供一个运行的例子,这里是代码:

# File: UI_Test.py
from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName(_fromUtf8("Dialog"))
        Dialog.resize(271, 70)
        self.pushButton_Ok = QtGui.QPushButton(Dialog)
        self.pushButton_Ok.setGeometry(QtCore.QRect(20, 20, 93, 28))
        self.pushButton_Ok.setObjectName(_fromUtf8("pushButton_Ok"))
        self.pushButton_Cancel = QtGui.QPushButton(Dialog)
        self.pushButton_Cancel.setGeometry(QtCore.QRect(130, 20, 93, 28))
        self.pushButton_Cancel.setObjectName(_fromUtf8("pushButton_Cancel"))

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

    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(_translate("Dialog", "Dialog", None))
        self.pushButton_Ok.setText(_translate("Dialog", "OK", None))
        self.pushButton_Cancel.setText(_translate("Dialog", "Cancel", None))

2 个答案:

答案 0 :(得分:4)

原始代码中的问题在本节中:

if True:
    qApp = QtGui.QApplication(sys.argv)
    Dialog = QtGui.QDialog()
    u = Testdialog()
    u.setupUi(Dialog)
    Dialog.exec_()
    sys.exit(qApp.exec_())

你想要的是这样的东西:

if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)
    u = Testdialog()
    u.show()
    sys.exit(app.exec_())

原始代码不起作用的原因是因为信号连接仅在__init__的{​​{1}}中进行。您创建的Testdialog实例已添加了所有ui,并且所有信号都已正确连接,但您实际上从未显示过!相反,您将显示您创建的其他对话框(即Testdialog),该对话框会添加相同ui的副本(通过Dialog }) - 但没有信号连接。

答案 1 :(得分:1)

嘿,这是我的回答。我只是在没有QtDesigner的情况下制作了相同的例子(只需复制粘贴并对其进行处理):

import sys
from PyQt4 import QtGui, QtCore
from PyQt4.Qt import pyqtSlot

class MyDialog(QtGui.QDialog):
    def __init__(self):
        super(MyDialog, self).__init__()
        self.resize(271, 70)
        self.pushButton_Ok = QtGui.QPushButton(self)
        self.pushButton_Ok.setGeometry(QtCore.QRect(20, 20, 93, 28))
        self.pushButton_Ok.setText("Ok")

        self.pushButton_Cancel = QtGui.QPushButton(self)
        self.pushButton_Cancel.setGeometry(QtCore.QRect(130, 20, 93, 28))
        self.pushButton_Cancel.setText("Cancel")

        # HERE the slots are connected
        self.pushButton_Ok.clicked.connect(self.clickedOk) # new style signal/slot
        self.pushButton_Cancel.clicked.connect(self.clickedCancel) # new style signal/slot

    @pyqtSlot()
    def clickedCancel(self):
        print ("Cancel pressed")

    @pyqtSlot()
    def clickedOk(self):
        print ("Ok pressed")

qApp = QtGui.QApplication(sys.argv)
dial = MyDialog()
dial.show()
sys.exit(qApp.exec_())

我希望你现在看到我的意思是不要使用QtDesigner。因为像这个例子一样,它更清晰,更少的代码你理解后台发生的事情越多越好。我希望我的回答对你有帮助。