为什么在PyQt中使用信号和槽?

3

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

我不理解信号和槽的原因。也就是说,似乎我可以通过直接调用类的方法来完成所有操作。这样做更符合Python风格,代码更少,更易于阅读。我错过了什么吗?

为了澄清,我想知道为什么要这样做:

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

当我能做到这一点时:
def mouseReleaseEvent(self): 
    ui.iconClicked()
3个回答

9
信号和槽的存在是因为您不能从应用程序的任何其他线程(除了UI线程)更改GUI。
如果您有一些需要大量CPU计算的任务,或者等待IO等任务......如果在UI线程执行(例如,如果您获取一个url或者持续一段时间的任务),则UI线程将处于繁忙状态,并且GUI事件循环无法更新自己,因此GUI看起来会冻结。
要执行这些类型的操作。您需要在单独的(后台工作)线程中执行它们,以便UI线程可以继续更新GUI。
现在的问题是,您不能从任何其他线程访问GUI的元素并更改其状态,除非是UI线程。因此引入了信号和槽。当您发出信号时,保证它会在UI线程中捕获,而槽将在UI线程中执行。
我不确定您在示例中试图实现什么,但这就是信号和槽存在的主要原因。基本上,UI线程应该只处理UI,其他所有操作都应该在后台工作线程中完成,该线程发送信号在UI线程中被捕获,更新GUI的槽在UI线程中执行。

4

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


4

除了@ViktorKerkez和@Wilbur的回答外,信号和槽提供了一种快速通知系统以及解耦类的功能。

这样做的一个很大的优点是,一个类可以发出一个信号,而不知道接收信息的对象是什么或者是谁。它可能只是连接了一个插槽的一个对象,也可能是几十个。或者,您可能希望一个单一的类只有一个插槽,该插槽连接到多个信号。因此,它可以用作通知系统。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接