Is there a way to create a signal from a class method in pyqt4 rather than always using instance methods?
I have a wrapper class that wraps and stores state between a QLineEdit and QCheckBox combination. The class sums all of the values in the QLineEdit in a class variable. If the QCheckBox is unchecked, the value of the associated line edit is deducted from the total. If the user edits the QLineEdit, the old value is deducted and the new value added. I want to emit the updated value everytime it changes from the class level.
Right now what I'm doing is passing in the QLineEdit instance that I'm dumping the value into and connecting that through all the wrapper instances.
What I'd love to do is have the following code snippet work.
QtCore.QObject.connect(Wrapper,Wrapper.sum_values_signal, line_edit_instance.setText)
It doesn't though. Here's my wrapper class for reference:
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))
In order to define a custom signal in a class, you need to use the pyqtSignal factory. Here is a simple example:
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()
Note that it uses new style signals that make the implementation really nice and straightforward.
EDIT: This is how you're supposed to connect the signals:
self.check_box.toggled.connect(self.check_box_toggled)
self.line_edit.textChanged.connect(self.line_edit_changed)
Then your code will probably fail because you don't handle the ValueError
on float(line_edit.text())
when the QLineEdit is empty.
Moreover, there is definitely some functional problems in your program, essentially linked to the way you handle sum_values
, and previous_value
. You could also consider getting rid of the sum_value
class attribute, since it seems like wrong design choice.
EDIT: Is this what you're trying to do by the way?
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_())
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.