[英]Pyqt5 signal and slot upon modifying a list
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.
基本上,我有一个列表,当附加到列表或更改大小以运行 function 时,我需要安装一个信号。 Below is a simple example of what I want.
下面是我想要的一个简单示例。 Is it doable in PyQt5 or there is no such thing?
它在 PyQt5 中可行还是没有这样的事情?
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.您可以创建
list
的子类并使用带有自定义信号的简单 QObject,然后覆盖所有可能更改列表大小的方法,以便您可以为每个方法发出信号。
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;请注意,在您的示例中,不会发出信号,因为您仅使用 getter 来获取现有的
res
object,然后为该列表调用 append 方法; the setter will never be called in that way.永远不会以这种方式调用 setter。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.