PyQt: диалоговое окно обтекания из кнопки QDesigner и Connect

Я начинаю изучать Python и PyQt. В настоящее время я борюсь с очень простой проблемой подключения сигналов и слотов с помощью диалоговых форм, сгенерированных из QDesigner. Я хочу подключить кнопку из QDialog. Код не генерирует ошибку. Диалог покажет, как и ожидалось. Но с нажатием на кнопки ничего не происходит.

В качестве альтернативы я попытался включить кодовую форму Ui_Dialog прямо в моем целевом классе Testdialog, Тогда связь работала. Кажется, я сделал ошибку в наследовании свойств от Ui_Dialog в Testdialog и / или так, как я хочу выполнить диалог.

Моя основная программа выглядит так:

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 ответа

Решение

Проблема в оригинальном коде находится в этом разделе:

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__ из Testdialog, Пример Testdialog Вы создаете все интерфейсы, добавленные к нему, и все сигналы подключены правильно, но вы никогда не показываете это! Вместо этого вы показываете другой диалог, который вы создали (т.е. Dialog), который получает новую копию того же интерфейса, добавленного к нему (через setupUi) - но без сигнальных соединений.

Привет, вот мой ответ. Я только что сделал тот же пример без 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. Потому что, как и в этом примере, он намного понятнее и меньше кода, и вы лучше понимаете, что происходит в фоновом режиме. Я надеюсь, что мой ответ помог вам.

Другие вопросы по тегам