首先,这是我的代码:
class PyQtObject(object):
class __PyQtObject(QObject):
my_signal = pyqtSignal()
def __init__(self):
QObject.__init__(self)
self.my_signal.connect(self.my_slot)
@pyqtSlot()
def my_slot(self):
print("call")
def call_in_main_thread(self):
print("should call")
print(self)
self.my_signal.emit()
instance = None
def __init__(self):
if PyQtObject.instance is None:
PyQtObject.instance = PyQtObject.__PyQtObject()
def __getattr__(self, name):
return getattr(self.instance, name)
这就是它应该如何运作:
我正在创建一个带有文本框的PyQt窗口,该窗口接收另一个线程的频繁更新,为其添加行。
这导致输出不稳定,因为QWidgets
的元素不应在PyQt主线外更改
您可以通过发出信号来解决这个问题,该信号连接到一个插槽,然后将这些行添加到文本字段中。
现在当你在很多地方都有这样的设置时,它对我有意义,将它外包给一个发出信号的功能,并从插槽中调用该功能。上面的代码是我想出来的。
现在问题是,这是结果输出:
should call
<object at ...ABCDEF>
call
should call
<object at ...ABCDEF>
...
should call
<object at ...ABCDEF>
call
如您所见,插槽仅偶尔调用。我可以完全计算3个电话,直到它完全停止被呼叫。除了第一个呼叫之外,这三个呼叫在它们之前有很多信号发射。打印对象以确保在调用插槽之前不会对内存变量进行内存清理。
这里出了什么问题?我测试过的事情:
我真的很茫然
更新我尝试了一种有两种选择的新方法:
caller_objects = []
class CallerObject(QObject):
signal = pyqtSignal()
def __init__(self, func: callable, args: tuple = None, kwargs: dict = None):
import threading
QObject.__init__(self)
self.func = func
self.args = args
self.kwargs = kwargs
self.signal.connect(self.slot)
# option 1
self.signal.emit()
# option 2
threading.Thread(target=self.signal.emit).start()
@pyqtSlot()
def slot(self):
print("call")
global caller_objects
if self.kwargs is not None:
if self.args is not None:
self.func(*self.args, **self.kwargs)
else:
self.func(**self.kwargs)
elif self.args is not None:
self.func(*self.args)
else:
self.func()
caller_objects.remove(self)
def call_in_main_thread(func: callable, args: tuple = None, kwargs: dict = None):
global caller_objects
caller_objects.append(CallerObject(func, args, kwargs))
选项1导致即时不可捕获的崩溃
选项2导致插槽被称为有时。我几乎不知道何时或为什么,但是当我在GUI中点击时有时会被调用。在日志中添加行call
。
太奇怪了