python pyqt signals-slots qpushbutton pyuic

python - PyQt: Diálogo de empaquetado del botón QDesigner y Connect



signals-slots qpushbutton (2)

Estoy empezando a aprender Python y PyQt. Actualmente estoy luchando con un problema muy básico sobre la conexión de señales y ranuras, con los formularios de diálogo generados desde QDesigner. Quiero conectar un botón de un QDialog. El código no genera un error. El cuadro de diálogo se muestra, como se esperaba. Pero al hacer clic en los botones no sucede nada.

Alternativamente, intenté incluir el código de Ui_Dialog directamente en mi clase objetivo Testdialog . Entonces la conexión estaba funcionando. Parece que Testdialog un error al heredar las propiedades de Ui_Dialog a Testdialog y / o en la forma en que quiero ejecutar el Diálogo.

Mi programa principal se ve así:

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_())

Cuando hago clic en los botones de bush, no pasa nada. Parece que la conexión no está funcionando.

¿Qué hice mal? ¿Cómo lo arreglas? ¿Qué más debería mejorarse?

El formulario UI_Test.py no es nada especial, ya que se genera automáticamente con QtDesigner y pyuic. Así que, básicamente, debería estar bien (aunque no entiendo todos los detalles sobre el código). Para proporcionar un ejemplo en ejecución, aquí está el código:

# 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))


El problema en el código original está en esta sección:

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

Lo que quieres en cambio es algo como esto:

if __name__ == ''__main__'': app = QtGui.QApplication(sys.argv) u = Testdialog() u.show() sys.exit(app.exec_())

La razón por la que el código original no funciona es porque las conexiones de señal solo se realizan en el __init__ de Testdialog . La instancia de Testdialog que Testdialog tiene toda la interfaz de Testdialog agregada, y todas las señales están conectadas correctamente, ¡pero nunca se muestra realmente! En cambio, muestra el otro cuadro de diálogo que ha creado (es decir, Dialog ), que obtiene una nueva copia de la misma interfaz de setupUi añadida (a través de setupUi ), pero sin las conexiones de señal.


Hola, esta es mi respuesta. Acabo de hacer el mismo ejemplo sin QtDesigner (solo copie y pegue):

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_())

Espero que veas ahora lo que quise decir con no usar el QtDesigner. Porque, como en este ejemplo, es mucho más claro y menos código, y usted comprende mejor lo que sucede en segundo plano. Espero que mi respuesta te haya ayudado.