我正在尝试将一个自定义对话框添加到我当前的GUI中,该对话框可以启动以供用户设置一些参数。理想情况下,我希望使用QtDesigner创建自定义对话框。以下是pyuic4
从对话框的QtDesigner ui代码中生成的代码。
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)
最后,在我的主GUI中,有一个带有以下代码的函数,应该会启动对话框
def exampleSubGui(self):
dialog = StartSub2(self)
result = dialog.exec_()
请注意,对话框尚未完成。一旦我解决了如何启动它,我将为滑块和编辑框添加信号/插槽连接。此外,如果我理解正确,我需要重载accept()
方法来返回用户的输入。
我遇到的第一个问题是StartSub2
的__init__
方法。我得到以下错误:
TypeError: unbound method setupUi() must be called with Ui_Dialog instance as
first argument (got StartSub2 instance instead)
我尝试采用与主GUI相同的方法,即使用以下代码
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
实例。有人能解释一下完成我想做的事情的正确方法吗?或者有人能给我一个明确的例子或参考吗?如果您需要更多信息或澄清,请告诉我。
class StartSub2(QtGui.QDialog, Ui_Dialog):
def __init__(self,parent=None):
QtGui.QDialog.__init__(self,parent)
self.setupUi(self)
应该可以解决初始化对话框的第一个问题。
为了获取信息,我通常会在StartSub2
中添加一个类似getValues
的方法,即
def getValues(self):
return somethingUseful
然后进行
dlg = StartSub2()
if dlg.exec_():
values = dlg.getValues()
# Do stuff with values
我只是想为设置带有返回值的自定义对话框提供我自己的答案(不回答特定于代码的问题,Whatang已经这样做了(。
我发现用一个可以根据需要返回不同内容的类方法构造一个简单的对话框类有点干净。我最近做了很多!这个想法是,类方法将构造对话框类的一个实例,并从实例中返回对象(在本例中为bool ok
(,这或多或少是一个工厂方法(据我所知,对OOP来说还是有点新(。
这是一个非常简单的对话框示例。将其扩展到对话框类中的任何需要都应该相对容易:
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()