【问题标题】:How to broadcast a signal in Qt4如何在 Qt4 中广播信号
【发布时间】:2011-12-10 09:12:49
【问题描述】:

我想要一个 Qt4 (PyQt4) 程序中的范例,其中组件能够在不知道信号来自何处的情况下响应信号。

我的初步阅读表明我必须明确地将信号连接到插槽。但我想要的是让许多组件中的任何一个能够发送信号,并让它被另一个组件处理。

与其他工具包相比,例如,在 wxWidgets 中,我会使用事件。这些会自动从子窗口/对象传播到父母。在每个级别都可以处理它们。这意味着如果我有很多可能发出相同事件的孩子,我不必将所有孩子都显式连接到处理程序。我可以将处理程序放在父级或窗口层次结构中的更高级别。这意味着只有事件生成器和消费者需要知道事件。消费者不需要知道事件的来源在哪里,有多少这样的来源,或者关于它的任何其他信息。

这在 Qt 中是否可行 - 还有其他方法吗?也许有信号和插槽的替代事件机制?

【问题讨论】:

  • 我不确定我是否理解你的意思,但你可以将信号连接到信号(所谓的触发)。或者,也许您想将许多具有相同信号的对象连接到一个插槽,并获取有关谁是发送者的信息?
  • 我在问题中添加了更多内容以试图澄清
  • 如果你想让信号表现为事件,为什么不直接使用events呢?
  • 嗨.. 一个非常好的问题。主要是因为我直到一天前才找到它们。我仍在尝试了解 Qt。显然这就是我需要的!我仍然有点不清楚它们是如何传播的。到目前为止我读过的文档说“一些事件从孩子传播到父母”,但我没有找到任何指定用户事件在发布到小部件或应用程序时如何传播的内容?例如,其他小部件以什么顺序查看它们.. 指向文档的指针欢迎!
  • 我之前的评论不是最有帮助的,所以我会在这里尝试修改。 QApplication::notify() 负责将事件传递给QObjects,这是熟悉QEvents 的良好起点。通过创建具有自定义类型的新实例并覆盖 notify() 来创建自定义 QEvent,以便它将这些事件传播到父小部件,并且您将具有与您在 wx 示例中描述的类似(如果不准确)的行为。

标签: python qt4 pyqt signals


【解决方案1】:

这并不容易 - 您必须了解信号对象和接收对象才能将两者连接起来。但是,根据您的需要,您可能可以设置一个在两者之间进行调解的类(因此带有信号的对象告诉类它们存在,并且有这样的信号,而带有插槽的对象告诉类它们存在并且有这样那样的插槽来连接到给定的信号,并且中介类跟踪这两者,在必要时进行连接)。

【讨论】:

  • 是的 .. 我想我可以创建一个单例类作为服务器的“邮箱”,用于连接信号发生器和插槽消费者。也许这是 Qt 中这种场景的正确设计模式?
  • 单例的问题在于它是应用程序范围的。我可能只想响应对话框或其他容器的子级生成的信号,而不是应用程序中其他地方的类似对象。如果我尝试在对话框中应用这种方法,那么信号发生器需要知道谁对他们的信号感兴趣,或者槽消费者需要知道何时创建新的信号发生器,以便他们可以连接到它们。其中任何一个都破坏了组件的模块化:-(
【解决方案2】:

您不只是想要一个好的老式方法调用吗?响应只是方法的返回值。

【讨论】:

  • 没有。我正在寻找的更像是一个广播事件。我得到的印象是 Qt 很好地支持面向对象的范式,但并不是真正的事件驱动范式。信号和槽允许比方法调用更松散的耦合——信号对象和槽接收器不需要相互了解。但是某个地方的对象确实需要知道它们两者,才能连接它们。
  • 我正在寻找的是更宽松的 - 没有任何东西可以连接事件生成器和消费者。生成器创建一个事件。消费者监听事件。消费者可以发信号表示它已经处理了该事件。根据潜在消费者在应用程序窗口树中的位置(即父/子窗口),该事件以定义的顺序可供潜在消费者使用。我认为 Qt 没有做这样的事情?
  • 我会说python使函数调用非常松散,但我认为你的意思是生成器和消费者的自动关联。在这种情况下,关联基于父/子关系。另一个想法:在构建时,让生成器对象(子对象)向上查看小部件层次结构以找到消费者。在生成器中存储一个给消费者的 ref,并随意调用它的方法。
  • 谢谢 - 这是我一直在寻找的东西,尽管在我的情况下,事件源是一个较低级别的小部件,可能不应该知道潜在的消费者。消费者可能会使用事件过滤器来捕获(间接)感兴趣的孩子的构造并连接到他们。我认为 rebus 上面建议的实现(使用 QCustomEvent 并覆盖 QApplication::notify)可能更干净。
【解决方案3】:

信号处理程序不知道发射器(仅信号类型),发射器不知道连接了哪些处理程序。许多处理程序可以连接到同一个信号,并按连接顺序执行。一个信号可以从很多地方发出。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-23
    • 2012-07-31
    • 2020-09-04
    • 1970-01-01
    相关资源
    最近更新 更多