PyQt4: создайте пользовательский диалог, который возвращает параметры - PullRequest
9 голосов
/ 23 апреля 2011

Я пытаюсь добавить настраиваемое диалоговое окно в мой текущий графический интерфейс, который может быть запущен для пользователя, чтобы установить некоторые параметры. В идеале я хотел бы создать собственный диалог, используя QtDesigner. Ниже приведен код, сгенерированный pyuic4 из пользовательского кода QtDesigner для диалогового окна.

from PyQt4 import QtCore, QtGui

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(508, 300)
        self.buttonBox = QtGui.QDialogButtonBox(Dialog)
        self.buttonBox.setGeometry(QtCore.QRect(150, 250, 341, 32))
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
        self.buttonBox.setObjectName("buttonBox")
        self.label = QtGui.QLabel(Dialog)
        self.label.setGeometry(QtCore.QRect(10, 120, 181, 31))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.label.setFont(font)
        self.label.setObjectName("label")
        self.sl_value = QtGui.QSlider(Dialog)
        self.sl_value.setGeometry(QtCore.QRect(220, 120, 161, 31))
        self.sl_value.setOrientation(QtCore.Qt.Horizontal)
        self.sl_value.setObjectName("sl_value")
        self.ed_value = QtGui.QLineEdit(Dialog)
        self.ed_value.setGeometry(QtCore.QRect(400, 120, 41, 31))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.ed_value.setFont(font)
        self.ed_value.setObjectName("ed_value")
        self.retranslateUi(Dialog)
        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"), Dialog.accept)
        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), Dialog.reject)
        QtCore.QMetaObject.connectSlotsByName(Dialog)


    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
        self.label.setText(QtGui.QApplication.translate("Dialog", "Set example value:", None, QtGui.QApplication.UnicodeUTF8))

Это сохраняется в Sub2.py Затем в моем основном файле Python я добавляю

from Sub2 import Ui_Dialog

Я создаю новый класс с именем StartSub2 со следующим кодом

class StartSub2(QtGui.QDialog):
    def __init__(self,parent=None):
        QtGui.QDialog.__init__(self,parent)
        self.ui = Ui_Dialog
        self.ui.setupUi(self)

Наконец, внутри моего основного графического интерфейса есть функция со следующим кодом, которая должна запустить диалоговое окно

def exampleSubGui(self):
    dialog = StartSub2(self)
    result = dialog.exec_()

Обратите внимание, что диалог не завершен. Как только я решу, как его запустить, я добавлю соединения «сигнал / слот» для ползунка и поля редактирования. Кроме того, если я правильно понимаю, мне нужно перегрузить метод accept(), чтобы вернуть вводимые пользователем данные.

Первая проблема, с которой я сталкиваюсь, - это метод __init__ из StartSub2. Я получаю следующую ошибку:

TypeError: unbound method setupUi() must be called with Ui_Dialog instance as
first argument (got StartSub2 instance instead)

Я пытаюсь использовать тот же подход, что и основной графический интерфейс, который использует следующий код

class StartQT4(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

Но это не жалуется на то, что setupUi() получает экземпляр StartQT4 вместо Ui_MainWindow. Может кто-нибудь объяснить правильный способ выполнить то, что я пытаюсь сделать? Или может кто-нибудь указать мне на четкий пример или ссылку? Пожалуйста, дайте мне знать, если вам нужна дополнительная информация или разъяснения.

Ответы [ 2 ]

18 голосов
/ 23 апреля 2011
class StartSub2(QtGui.QDialog, Ui_Dialog):
    def __init__(self,parent=None):
        QtGui.QDialog.__init__(self,parent)
        self.setupUi(self)

должен решить вашу первую проблему с инициализацией диалогового окна.

Чтобы получить информацию, я обычно добавляю метод, называемый чем-то вроде getValues в StartSub2, то есть

def getValues(self):
    return somethingUseful

тогда делай

dlg = StartSub2()
if dlg.exec_():
    values = dlg.getValues()
    # Do stuff with values
2 голосов
/ 05 июня 2018

Просто хотел предоставить свой собственный ответ для настройки пользовательского диалога с возвращаемыми значениями (не отвечая на вопросы, специфичные для кода, что уже делал Ванганг).

Мне показалось немного чище построить простой диалогкласс с методом класса , который может возвращать разные вещи по мере необходимости.Я делал это много в последнее время!Идея состоит в том, что метод класса будет создавать экземпляр класса диалога и возвращать объекты из экземпляра (в данном случае bool ok), который является более или менее фабричным методом (из чегоВ любом случае, я все еще немного новичок в ООП.

Вот очень упрощенный пример диалога.Относительно легко распространить это на все, что вам нужно внутри класса диалога:

class OkDialog(QtGui.QDialog):
    def __init__(self, parent):
        super(OkDialog, self).__init__(parent)

        self.ok = False

        self.btn_ok = QtGui.QPushButton("Ok", self)
        self.btn_ok.clicked.connect(self.button_press)
        self.btn_cancel = QtGui.QPushButton("Cancel", self)
        self.btn_cancel.clicked.connect(self.button_press)
        self.btn_cancel.move(80, 0)

    def button_press(self):
        if self.sender() == self.btn_ok:
            self.ok = True
        self.close()

    @classmethod
    def isOkay(cls, parent):
        dialog = cls(parent)
        dialog.exec_()
        return dialog.ok

Прелесть в том, что когда приходит время создавать этот диалог, вы можете сделать это всего одной строкой OkDialog.isOkay(parent),Собираем все вместе в полностью рабочий образец:

import sys
from PyQt4 import QtCore, QtGui

class OkDialog(QtGui.QDialog):
    def __init__(self, parent):
        super(OkDialog, self).__init__(parent)

        self.ok = False

        self.btn_ok = QtGui.QPushButton("Ok", self)
        self.btn_ok.clicked.connect(self.button_press)
        self.btn_cancel = QtGui.QPushButton("Cancel", self)
        self.btn_cancel.clicked.connect(self.button_press)
        self.btn_cancel.move(80, 0)

    def button_press(self):
        if self.sender() == self.btn_ok:
            self.ok = True
        self.close()

    @classmethod
    def isOkay(cls, parent):
        dialog = cls(parent)
        dialog.exec_()
        return dialog.ok

class Ui_Dialog(QtGui.QDialog):
    def __init__(self):
        super(Ui_Dialog, self).__init__()

        button = QtGui.QPushButton("Launch custom dialog", self)
        button.pressed.connect(self.launch_dialog)

    def launch_dialog(self):
        print OkDialog.isOkay(self)

def main():
    app = QtGui.QApplication(sys.argv)
    ex = Ui_Dialog()

    ex.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()
...