My question may not be clear. Basically, I have a list and I need to install a signal when appending to the list or change size to run a function. Below is a simple example of what I want. Is it doable in PyQt5 or there is no such thing?
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot
class MyList(QObject):
# Signal emitted when the list is resized, int:newsize
resized = pyqtSignal(list)
def __init__(self):
QObject.__init__(self)
# "Hide" the values and expose them via properties
self._list = [1,2]
@property
def res(self):
return self._list
@res.setter
def res(self, new_list):
self._list.append(new_list)
self.resized.emit(new_list)
# A slot for the "resized" signal, accepting the radius
@pyqtSlot(list)
def on_resized(r):
print('resized', r)
c = MyList()
#
c.resized.connect(on_resized)
#
c.res.append(20)
# delete all
c.res[:] = []
You can create a subclass of list
and use a simple QObject with a custom signal for it, then override all methods that might change the size of the list so that you can emit the signal for each of them.
class ListProxy(QtCore.QObject):
resized = QtCore.pyqtSignal(list)
class SignalList(list):
def __init__(self, *args):
super().__init__(*args)
self._proxy = ListProxy()
self.resized = self._proxy.resized
def append(self, item):
super().append(item)
self.resized.emit(self)
def extend(self, iterable):
super().extend(iterable)
self.resized.emit(self)
def pop(self, *args):
item = super().pop(*args)
self.resized.emit(self)
return item
# this is required for slicing -> myList[:] = []
# you might want to check if the length of the list is actually changed
# before emitting the signal
def __setitem__(self, *args, **kwargs):
super().__setitem__(*args, **kwargs)
self.resized.emit(self)
def __delitem__(self, *args, **kwargs):
super().__delitem__(*args, **kwargs)
self.resized.emit(self)
# this is required for concatenation -> myList += iterable
def __iadd__(self, *args, **kwargs):
super().__iadd__(*args, **kwargs)
self.resized.emit(self)
return self
Note that in your example the signal won't be emitted, because you are only using the getter to get the existing res
object, then you call the append method for that list; the setter will never be called in that way.
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.