3

我正在学习 PyQt(我以前没有使用过 C++ Qt)。

我不明白信号和插槽的原因。也就是说,似乎我可以通过直接调用类的方法来做任何事情。这样做看起来更 Pythonic,使用更少的代码并且更容易阅读。我错过了什么?

为了澄清,我问我为什么要这样做:

def mouseReleaseEvent(self):  
    self.clicksignal.connect(ui.iconClicked) 
    self.clicksignal.emit()

当我可以这样做时:

def mouseReleaseEvent(self): 
    ui.iconClicked()
4

3 回答 3

8

信号和槽存在的原因是因为您不能从应用程序的任何其他线程(除了 UI 线程)更改 GUI。

如果您有一些繁重的 CPU 密集型计算要做,或者任何等待 IO 或类似的任务......线程将很忙,并且 GUI 事件循环将无法自行更新,因此 GUI 看起来会冻结。

做这些操作。您在单独的(后台工作人员)线程中执行它们,因此 UI 线程可以继续更新 GUI。

现在的问题是您无法访问 GUI 的元素并从除 UI 线程之外的任何其他线程更改它们的状态。所以引入了信号和槽。当您发出一个信号时,它保证会在 UI 线程中被捕获,并且插槽将在 UI 线程中执行。

我不确定您在示例中尝试完成什么,但这是信号和插槽存在的主要原因。基本上,UI 线程应该只处理 UI,其他一切都应该在后台工作线程中完成,该线程发送一个信号,该信号被捕获在 UI 线程中,并且更新 GUI 的插槽在 UI 线程中执行。

于 2013-09-02T07:57:15.250 回答
4

嗯......是的,你可以。但你需要想得更大。在您的示例代码中,调用者mouseReleaseEvent必须具有对接收通知的对象的引用,并显式调用适当的方法。使用插槽和信号机制将事件生产者(例如小部件)与事件消费者分离 - 几乎是任意其他对象。这使得设置通信和控制流更容易并且在低级 UI 组件外部,这是一件好事。它还使此类组件可重用——通过将接线代码移到外部,我们使其独立于应用程序逻辑。

于 2013-09-02T07:57:39.847 回答
4

除了@ViktorKerkez 和@Wilbur 的答案之外,信号和插槽还提供了一个通知系统,即一旦发生即忘记,以及解耦类。

这样做的一个很大的好处是一个类可以发出一个信号,而不知道什么或谁将接收到这个消息。它可能只是一个连接了插槽的对象,也可能是几十个。或者,您可能需要一个带有一个插槽的类,该插槽连接到多个信号。所以它可以用作通知系统。

例如,想象一个程序,其中许多不同类型的对象将信息发送到日志。这些对象只是发出一个 Log(text) 信号,并不关心实际记录的内容。这些信号可以连接到日志类,该类可以记录到文件、通过网络、屏幕或一次全部记录。记录的对象不在乎。

于 2013-09-02T08:49:46.660 回答