使用重载的 PySide 信号调用 Python 函数而不传递参数
Posted
技术标签:
【中文标题】使用重载的 PySide 信号调用 Python 函数而不传递参数【英文标题】:Call Python function with overloaded PySide signal without passing arguments 【发布时间】:2020-11-23 20:22:51 【问题描述】:我正在尝试以不同的方式从线程工作者调用 PySide 应用程序中的相同函数。用test_sig = Signal((), (int,), (str,))
重载PySide信号,提供三个槽(@Slot()
、@Slot(int)
和@Slot(str)
)给一个测试函数,然后发出每个信号(test_sig.emit()
、test_sig[int].emit(1)
和test_sig[str].emit('a')
)适用于整数和字符串的情况。但是,无论我尝试什么,我都无法在没有传递参数的情况下调用测试函数。
从我的尝试看来,当信号过载时,发出test_sig.emit()
不会立即发出。仅当发出下一个定义的重载信号中的第一个(在我的情况下为[str]
)时,才会发出两次。
我正在使用 Python 3.9 和 PySide==1.15.1。这是我的最小工作示例:
import sys
from PySide2.QtCore import QRunnable, QObject, QThreadPool, Slot, Signal
from PySide2.QtWidgets import QApplication, QMainWindow
# Signals class
class WorkerSignals(QObject):
test_sig = Signal((), (str,), (int,))
finished = Signal()
# Test worker
class Worker(QRunnable):
def __init__(self):
super().__init__()
self.signals = WorkerSignals()
@Slot()
def run(self):
self.signals.test_sig.emit() # Trying to call function with no args
self.signals.test_sig[int].emit(1) # Call function with int
self.signals.test_sig[str].emit('a') # Call function with str
self.signals.finished.emit()
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.threadpool = QThreadPool()
self.run_test()
def run_test(self):
worker = Worker()
worker.signals.test_sig.connect(self.test_func) # I suspect this might be what I'm doing wrong
worker.signals.test_sig[int].connect(self.test_func)
worker.signals.test_sig[str].connect(self.test_func)
worker.signals.finished.connect(self.test_finished)
self.threadpool.start(worker)
@Slot()
@Slot(int)
@Slot(str)
def test_func(self, arg=None):
test_result = 'Test reached'
if arg:
test_result += f', arg received and is a type(arg).'
else:
test_result += ' and no arg received.'
print(test_result)
@Slot()
def test_finished(self):
self.close()
if __name__ == '__main__':
app = QApplication(sys.argv)
main_window = MainWindow()
sys.exit(app.exec_())
其终端输出为:
Test reached, arg received and is a <class 'int'>.
Test reached, arg received and is a <class 'str'>.
Test reached, arg received and is a <class 'str'>.
我发现的唯一解决方法是使用test_sig = Signal((int,), (str,))
重载信号,使用test_sig.emit(None)
发射而不连接test_sig.connect()
信号,这会导致以下终端输出:
Test reached and no arg received.
Test reached, arg received and is a <class 'int'>.
Test reached, arg received and is a <class 'str'>.
【问题讨论】:
【参考方案1】:这显然是一个错误。这样Signal
不允许在没有参数的情况下建立过载信号,而且它不会消除先前信息的缓冲区。
另一方面,在pyqt5 中,观察到了预期的行为,因此我们可以指出这不是qt 错误,而只是pyside2。
我创建了PYSIDE-1427
错误。
【讨论】:
以上是关于使用重载的 PySide 信号调用 Python 函数而不传递参数的主要内容,如果未能解决你的问题,请参考以下文章
PySide2 使用 QProgressBar 作为信号参数