使用pyqt4创建类信号
有没有办法在pyqt4中从类的方法创建信号,而不是总是使用实例方法呢?
我有一个包装类,它用来在QLineEdit和QCheckBox之间存储状态。这个类会把QLineEdit中的所有值加起来,存储在一个类变量里。如果QCheckBox没有被选中,相关的QLineEdit的值就会从总值中减去。如果用户修改了QLineEdit的内容,旧的值会被减去,新的值会被加上。我想在每次值变化时,从类的层面发出更新的信号。
现在我做的是把我想要放值的QLineEdit实例传进去,并通过所有的包装实例连接它。
我希望能让下面的代码片段正常工作。
QtCore.QObject.connect(Wrapper,Wrapper.sum_values_signal, line_edit_instance.setText)
但实际上并没有。以下是我的包装类供参考:
class Wrapper(QtCore.QObject):
sum_values = 0
sum_values_signal = QtCore.pyqtSignal(str)
def __init__(self, line_edit, check_box):
super(QtCore.QObject, self).__init__()
self.check_box = check_box
self.line_edit = line_edit
Wrapper.sum_values += float(line_edit.text())
self.previous_value = float(line_edit.text())
QtCore.QObject.connect(self.check_box,
QtCore.SIGNAL(_fromUtf8("toggled(bool)")),
self.update_sum_values_wrt_check_box)
QtCore.QObject.connect(self.line_edit,
QtCore.SIGNAL(_fromUtf8("textChanged(QString)")),
self.update_sum_values_wrt_line_edit)
def update_sum_values_wrt_check_box(self, toggled):
if toggled is False:
Wrapper.sum_values -= self.previous_value
else:
Wrapper.sum_values += self.previous_value
self.sum_values_signal.emit(text(Wrapper.sum_values))
def update_sum_values_wrt_line_edit(self, string):
Wrapper.sum_values -= self.previous_value
Wrapper.sum_values += float(string)
self.previous_value = float(string)
self.sum_values_signal.emit(text(Wrapper.sum_values))
1 个回答
1
为了在一个类里定义一个自定义信号,你需要使用 pyqtSignal 这个工厂。下面是一个简单的例子:
class CustomWidget(QtGui.QWidget):
# No argument signal
custom_signal = QtCore.pyqtSignal()
# Signal with int argument and a custom name
custom_signal_int = QtCore.pyqtSignal(int, name='integerSignal')
def atSomePointEvent(self, event):
value = event.someValue()
if isinstance(value, int):
self.custom_signal_int.emit(value)
else:
self.custom_signal.emit()
注意,这里使用了 新风格信号,这样实现起来非常简单明了。
编辑:这是你应该连接信号的方式:
self.check_box.toggled.connect(self.check_box_toggled)
self.line_edit.textChanged.connect(self.line_edit_changed)
然后你的代码可能会出错,因为当 QLineEdit 为空时,你没有处理 float(line_edit.text())
的 ValueError
。
而且,你的程序中肯定存在一些功能性问题,主要和你处理 sum_values
和 previous_value
的方式有关。你也可以考虑去掉 sum_value
这个类属性,因为这似乎是个错误的设计选择。
编辑:顺便问一下,这就是你想要做的事情吗?
from PyQt4 import QtCore, QtGui
class CustomLabel(QtGui.QLabel):
def __init__(self, line_edit_lst):
super(CustomLabel, self).__init__("0")
self.line_edit_lst = line_edit_lst
for line_edit in self.line_edit_lst:
line_edit.textChanged.connect(self.update)
def update(self, ignore):
total = sum(self.str_to_float(line_edit.text())
for line_edit in self.line_edit_lst)
self.setText(str(total))
def str_to_float(self, string, default=0):
try: return float(string)
except ValueError: return default
class MyDialog(QtGui.QDialog):
def __init__(self, parent=None):
super(MyDialog, self).__init__(parent)
hbox = QtGui.QVBoxLayout()
self.lines = [QtGui.QLineEdit() for _ in range(5)]
for line in self.lines:
hbox.addWidget(line)
self.label = CustomLabel(self.lines)
hbox.addWidget(self.label)
self.setLayout(hbox)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
w = MyDialog()
w.show()
sys.exit(app.exec_())