3

I have written the application in Java using Swing and now I'm trying to rewrite it in C++. The program in Java had Controller which had references to Model, View and BlockingQueue for the events. When something happened in View new event was putted into BlockingQueue and processed by Controller and Model. Then some action was invoked in Swing by SwingUtilities.invokeLater().

How to do something like this in C++ using Qt? I have written the model but I don't know how to connect it with UI written in Qt via something like BlockingQueue from Java.

Avas
  • 31
  • 2

3 Answers3

1

If possible, I would avoid using threads. Without any more clarification from your side, I would recommend you take a look at the Qt documentation for signals and slots. Briefly put, signals and slots are the default way of event handling in Qt. Interacting with a widget causes signals to be triggered. Your classes can connect themselves to such a signal and react to it.

I realize that this answer is quite vague. If you add some more details about what you want to accomplish exactly, I will happily update it :)

Gnosophilon
  • 1,340
  • 7
  • 24
1

The equivalent to a BlockingQueue is inherent in each QObject. It's not explicitly stated in the Qt documentation for QObject (like it should be!), but there is an event queue effectively for every QObject out there. You can use the static QCoreApplication::postEvent method to post events to any QObject, from any thread -- as long as you have a pointer to a QObject, you can post events to it.

Signal-slot connections of the Qt::QueuedConnection type use that same event queue to post internal QMetaCallEvent events. Those events are picked up by QObject::event() and result in calls to relevant slots. When control goes back to the thread's event loop, the latter looks at the event queue and passes events to the QObject::event() methods.

Those built-in event queues are very useful because they inherently let you serialize the access to a QObject, so you don't have to add extra synchronization primitives, and you avoid setting yourself up for deadlocks. Using ad-hoc synchronization leads to trouble, even Java got things wrong by design, unfortunately. See Herb Sutter's excellent exposes on this topic: The Many Faces of a Deadlock and Avoid Calling Unknown Code While Inside a Critical Section. He has plenty of other publications on this and related topics, it's a true treasure trove of knowledge. He also explains how to design run-to-completion, short-and-sweet asynchronous applications for good performance.

If you base your design on QObjects and connections between them using signals-slots and event posting, you're ready to move any of those QObjects to a dedicated QThread should your profiling/benchmarking indicate a need of doing so. Anything that derives from a QWidget cannot leave the GUI thread, though.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • Is the event queue associated with the QObject, or with the QThread to which the QObject belongs? I'm used to moving a QObject to a new QThread using, e.g., `worker = new QThread; moveToThread(worker); worker->start();`. Then anything `connect`ed with `Qt::QueuedConnection` will automatically use that thread's event queue. Is this the queue you are talking about? – Josiah Yoder Apr 12 '17 at 22:36
  • To the user of `QObject` it appears as if the queue was specific to the object, because the user of an object doesn't see the events delivered to any other objects, and the behavior is the same no matter what thread the object is in. That the queue really belongs to the outermost event loop created in a given thread is an implementation detail. It has some implications for performance, i.e. there are corner cases where you can get quadratic behavior if you're not careful because of this detail. But in most cases it doesn't matter. – Kuba hasn't forgotten Monica Apr 13 '17 at 14:30
0

Sounds like you want to make a worker class using QThread. Take a look at Qt' Mandelbrot example of work being done in a thread that responds to GUI events: http://doc.qt.io/qt-4.8/qt-threads-mandelbrot-example.html

Daniel Kamil Kozar
  • 18,476
  • 5
  • 50
  • 64
MrFox
  • 1,244
  • 1
  • 11
  • 24