我开始使用PyQt4
编写GUI。这是我第一次使用 GUI(而且 oo-programming 对我来说有些陌生(。该 GUI 的一部分将类似于 4 到 5 个 QComboBox
实例 .由于要做出许多选择,我希望用户能够锁定一个选择,这样以后就不会随意更改。对于一个QComboBox,我可以用我编写的这段代码解决问题:
import sys
from PyQt4 import QtGui, QtCore
class MyGui(QtGui.QWidget):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.resize(250, 50)
# vertical layout for widgets
self.vbox = QtGui.QVBoxLayout()
self.setLayout(self.vbox)
# Create a combo box with some choices
self.combo_color = QtGui.QComboBox()
self.vbox.addWidget(self.combo_color)
items = 'Red Yellow Purple'.split()
self.combo_color.addItems(items)
self.connect(self.combo_color, QtCore.SIGNAL('activated(QString)'), self.use_choice)
# add a checkbox next to the combobox which (un-)locks the the combo-choice
self.checkbox_color = QtGui.QCheckBox('Lock Choice', self)
self.vbox.addWidget(self.checkbox_color)
self.connect(self.checkbox_color, QtCore.SIGNAL('stateChanged(int)'), self.lock_choice)
def use_choice(self, text):
# do something very useful with the choice
print 'The current choice is: {choice}'.format(choice=text)
def lock_choice(self):
if self.checkbox_color.isChecked():
self.combo_color.setEnabled(False)
print 'Choice {choice} locked'.format(choice=self.combo_color.currentText())
else:
self.combo_color.setEnabled(True)
print 'Choice unlocked'
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
mygui = MyGui()
mygui.show()
app.exec_()
这段代码做了它应该做的事情,但我对它的设计非常不满意,因为lock_choice
的方法被硬编码为只锁定 QComboBox combo_color
的选择。如果我现在想对另一个QComboBox(比如combo_name
(和第二个QCheckBox(比如checkbox_name
(做同样的事情,这可以通过将以下代码附加到类__init__(self)
代码块来实现:
# create second combo box with some other choices
self.combo_name = QtGui.QComboBox()
self.vbox.addWidget(self.combo_name)
items = 'Bob Peter'.split()
self.combo_name.addItems(items)
self.connect(self.combo_name, QtCore.SIGNAL('activated(QString)'), self.use_choice)
# add a checkbox next to the combobox which (un-)locks the the combo-choice
self.checkbox_name = QtGui.QCheckBox('Lock Choice', self)
self.vbox.addWidget(self.checkbox_name)
self.connect(self.checkbox_name, QtCore.SIGNAL('stateChanged(int)'), self.lock_choice) # <-- obviously wrong, as it (un-)locks color choice at the moment
两个QComboBox现在可以use_choice()
共享方法,但它们不能lock_choice()
共享方法,因为两个复选框都锁定了颜色选择。我希望复选框checkbox_name
锁定名称选择,而无需复制和粘贴当前的lock_choice()
方法并切换硬编码的组合框。我相信有一个简单的方法,比如将目标组合框传递给方法,我只是还不知道。帮助将不胜感激!
尝试部分函数-
from functools import partial
使用连接信号,传递 QWidget 名称:
self.connect(self.checkbox_color, QtCore.SIGNAL('stateChanged(int)'), partial(self.lock_choice, self.combo_color))
在您的方法中,您可以添加一个参数。
我们将在方法中添加一个参数,如下所示,以处理我们将通过上面的部分函数传递的 QWidget(QComboBox(。
def lock_choice(self, combos):
if combos.isEnabled(True):
combos.setEnabled(False)
print 'Choice {choice} locked'.format(choice=combos.currentText())
最简单的解决方案是将切换信号与 setDisabled 插槽一起使用:
self.checkbox_color.toggled.connect(self.combo_color.setDisabled)
(请注意,在进行信号连接时,新式sytax的清洁程度(。
还值得指出的是,您还可以使用lambda
进行内联信号连接,如下所示:
self.checkbox_color.toggled.connect(
lambda checked: self.combo_color.setDisabled(checked))
当没有方便的信号/插槽配对时,这可能是最惯用的解决方案(当然,部分函数可以以不同的方式实现或多或少相同的事情(。