我已经使用Swing在Java中编写了应用程序,现在我正在尝试用C ++重写它。 Java中的程序有一个Controller,它引用了事件的Model,View和BlockingQueue。当View中发生了某些事件时,新事件被放入BlockingQueue并由Controller和Model处理。然后在Swing by SwingUtilities.invokeLater()中调用了一些动作。
如何使用Qt在C ++中做这样的事情?我已经编写了模型,但我不知道如何通过类似于来自Java的BlockingQueue之类的东西将它与用Qt编写的UI连接起来。
答案 0 :(得分:1)
如果可能的话,我会避免使用线程。如果没有您方面的任何澄清,我建议您查看Qt documentation for signals and slots。简而言之,信号和插槽是Qt中事件处理的默认方式。与小部件交互会导致信号被触发。您的课程可以连接自己发送信号并对其做出反应。
我意识到这个答案很模糊。如果你添加一些关于你想要完成的什么的更多细节,我会很高兴地更新它:)
答案 1 :(得分:1)
每个QObject
都固有相当于BlockingQueue的内容。在Qt的Qt文档中没有明确说明(就像它应该的那样!),但是每个QObject都有一个有效的事件队列。您可以使用静态QCoreApplication::postEvent
方法从任何线程向任何QObject发布事件 - 只要您有指向QObject的指针,就可以向其发布事件。
Qt::QueuedConnection
类型的信号槽连接使用相同的事件队列来发布内部QMetaCallEvent
事件。这些事件由QObject::event()
选取,并导致对相关广告位的调用。当控制返回到线程的事件循环时,后者查看事件队列并将事件传递给QObject::event()
方法。
这些内置事件队列非常有用,因为它们本身允许您序列化对QObject的访问,因此您不必添加额外的同步原语,并且可以避免设置自己的死锁。使用ad-hoc同步会导致麻烦,甚至Java在设计上也会出错。请参阅Herb Sutter对此主题的出色展示:The Many Faces of a Deadlock和Avoid Calling Unknown Code While Inside a Critical Section。他有很多其他的publications on this and related topics,这是一个真正的宝库。他还解释了如何设计从运行到完成,短而甜的异步应用程序以获得良好的性能。
如果您的设计基于QObjects以及使用信号槽和事件发布之间的连接,那么如果您的分析/基准测试表明需要这样做,您就可以将这些QObject中的任何一个移动到专用的QThread。但是,任何源自QWidget的东西都不能离开GUI线程。
答案 2 :(得分:0)
听起来你想使用QThread创建一个worker类。看看Qt'Mandelbrot在响应GUI事件的线程中完成的工作示例:http://doc.qt.io/qt-4.8/qt-threads-mandelbrot-example.html