#python #user-interface #pyqt4
#python #пользовательский интерфейс #pyqt4
Вопрос:
Я пытаюсь добавить пользовательское диалоговое окно в мой текущий графический интерфейс, которое может быть запущено пользователем для установки некоторых параметров. В идеале я хотел бы создать пользовательский диалог с помощью 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
экземпляра. Кто-нибудь может объяснить правильный способ выполнить то, что я пытаюсь сделать? Или кто-нибудь может указать мне на наглядный пример или ссылку? Пожалуйста, дайте мне знать, если вам нужна дополнительная информация или разъяснения.
Ответ №1:
class StartSub2(QtGui.QDialog, Ui_Dialog):
def __init__(self,parent=None):
QtGui.QDialog.__init__(self,parent)
self.setupUi(self)
должно решить вашу первую проблему с инициализацией диалога.
Чтобы получить информацию обратно, я обычно добавляю метод, называемый чем-то вроде getValues
to StartSub2
, т.Е.
def getValues(self):
return somethingUseful
затем выполните
dlg = StartSub2()
if dlg.exec_():
values = dlg.getValues()
# Do stuff with values
Комментарии:
1. Стоит отметить, что это не сработает, если вы self.close() диалоговое окно (поскольку значение, возвращаемое из .exec() равно 0), вы должны self.accept() . Сначала это было не совсем понятно для меня из старого школьного синтаксиса SIGNAL в вопросе.
Ответ №2:
Просто хотел предоставить свой собственный ответ для настройки пользовательского диалога с возвращаемыми значениями (не отвечая на вопросы, касающиеся конкретного кода, что Whatang уже сделал).
Я обнаружил, что было бы немного чище создать простой класс dialog с методом класса, который может возвращать разные вещи по мере необходимости. В последнее время я часто их создаю! Идея заключается в том, что метод class создаст экземпляр класса dialog и вернет объекты из экземпляра (в данном случае bool ok
), который является более или менее фабричным методом (насколько я понимаю, в любом случае, все еще несколько новым для ООП).
Вот очень упрощенный пример диалога. Должно быть относительно легко расширить это до всего, что вам нужно в классе dialog:
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()