3

我已经使用 Swing 用 Ja​​va 编写了应用程序,现在我正在尝试用 C++ 重写它。Java 中的程序有控制器,它有对事件的模型、视图和 BlockingQueue 的引用。当 View 发生某些事情时,新事件被放入 BlockingQueue 并由 Controller 和 Model 处理。然后 SwingUtilities.invokeLater() 在 Swing 中调用了一些动作。

如何使用 Qt 在 C++ 中做这样的事情?我已经编写了模型,但我不知道如何通过 Java 中的 BlockingQueue 之类的东西将它与用 Qt 编写的 UI 连接起来。

4

3 回答 3

1

如果可能的话,我会避免使用线程。如果您没有更多的说明,我建议您查看Qt 文档中的信号和插槽。简而言之,信号和槽是 Qt 中事件处理的默认方式。与小部件交互会导致触发信号。您的类可以自己连接到这样的信号并对其做出反应。

我意识到这个答案很模糊。如果你添加更多关于想要完成的细节,我会很乐意更新它:)

于 2012-06-01T15:48:51.967 回答
1

BlockingQueue 的等价物是每个QObject. 它没有在 QObject 的 Qt 文档中明确说明(应该是这样!),但是对于每个 QObject 都有一个有效的事件队列。您可以使用静态QCoreApplication::postEvent方法从任何线程向任何 QObject 发布事件——只要您有一个指向 QObject 的指针,您就可以向它发布事件。

该类型的信号槽连接Qt::QueuedConnection使用相同的事件队列来发布内部QMetaCallEvent事件。这些事件被拾取QObject::event()并导致对相关插槽的调用。当控制返回到线程的事件循环时,后者查看事件队列并将事件传递给QObject::event()方法。

那些内置的事件队列非常有用,因为它们本质上允许您序列化对 QObject 的访问,因此您不必添加额外的同步原语,并且您可以避免陷入死锁。使用 ad-hoc 同步会带来麻烦,不幸的是,即使是 Java 在设计上也出错了。请参阅 Herb Sutter 关于此主题的出色公开:死锁的许多方面避免在关键部分中调用未知代码。他有很多关于这个和相关主题的其他出版物,这是一个真正的知识宝库。他还解释了如何设计从运行到完成的、简短的异步应用程序以获得良好的性能。

如果您的设计基于 QObjects 以及它们之间使用信号槽和事件发布的连接,那么如果您的分析/基准测试表明需要这样做,您就可以将这些 QObjects 中的任何一个移动到专用的 QThread。但是,任何从 QWidget 派生的东西都不能离开 GUI 线程。

于 2012-06-01T19:45:03.353 回答
0

听起来您想使用 QThread 创建一个工人类。看一下 Qt' Mandelbrot 在响应 GUI 事件的线程中完成的工作示例:http: //doc.qt.io/qt-4.8/qt-threads-mandelbrot-example.html

于 2012-06-01T15:36:55.360 回答