将Java应用程序移植到C++ (Qt)

3

我已经使用Swing在Java中编写了应用程序,现在我正在尝试用C++重新编写它。Java程序中有一个Controller,其中包含对Model、View和BlockingQueue事件的引用。当View中发生某些事情时,新的事件被放入BlockingQueue中,并由Controller和Model处理。然后通过SwingUtilities.invokeLater()在Swing中调用一些操作。

如何在C++中使用Qt实现类似于Java中的这种功能呢?我已经编写了模型,但不知道如何通过类似于Java中的BlockingQueue将其与Qt中编写的UI连接起来。


你是指Java Native Interface吗? - Paul Vargas
3个回答

1
如果可能的话,我会避免使用线程。在没有更多明确的信息的情况下,我建议您查看Qt信号和槽的文档。简而言之,信号和槽是Qt中事件处理的默认方式。与小部件交互会触发信号。您的类可以将自己连接到这样的信号并对其做出反应。
我知道这个答案相当模糊。如果您添加有关您想要实现的确切细节,我将很乐意更新它 :)

1
每个QObject中都有一个类似于BlockingQueue的等效物。虽然Qt文档中没有明确说明(但应该有!),但实际上每个QObject都有一个事件队列。您可以使用静态的QCoreApplication::postEvent方法将事件发布到任何QObject,从任何线程--只要您有指向QObject的指针,就可以将事件发布到它。 Qt::QueuedConnection类型的信号槽连接也使用相同的事件队列来发布内部的QMetaCallEvent事件。这些事件由QObject::event()捕获,并导致调用相关的槽。当控制返回线程的事件循环时,后者会查看事件队列并将事件传递给QObject::event()方法。

那些内置的事件队列非常有用,因为它们本质上让您序列化对QObject的访问,因此您不必添加额外的同步原语,并且避免设置自己陷入死锁。使用临时同步会导致麻烦,即使Java在设计上也犯了错误。请参阅Herb Sutter关于此主题的出色文章:The Many Faces of a DeadlockAvoid Calling Unknown Code While Inside a Critical Section。他还有很多其他与此相关的出版物,这是一个真正的知识宝库。他还解释了如何设计运行到完成、简短而甜美的异步应用程序以获得良好的性能。

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


与 QObject 相关联的事件队列是与 QObject 所属的 QThread 相关联的吗?我习惯于使用 worker = new QThread; moveToThread(worker); worker->start(); 将 QObject 移动到新的 QThread 中。然后,任何使用 Qt::QueuedConnection 连接的内容都会自动使用该线程的事件队列。这就是你所说的队列吗? - Josiah Yoder
对于QObject的用户而言,队列似乎是特定于该对象的,因为对象的用户看不到传递给任何其他对象的事件,并且无论对象在什么线程中,行为都是相同的。队列真正属于在给定线程中创建的最外层事件循环是一些实现细节。这对性能有一些影响,即由于此细节,在某些边缘情况下,如果不小心的话,你可能会得到二次行为。但在大多数情况下,这并不重要。 - Kuba hasn't forgotten Monica

0

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