最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - Mixing Qt with Motif in same application - Stack Overflow

programmeradmin3浏览0评论

I have a legacy application using Motif graphics that I am trying to migrate forward to modern times. Rewriting all at once is a hard-sell (and risky) so I'd like to slowly migrate one window at a time to Qt. Any given window would be wholly Qt or Motif.

One issue I can think of is where each app.exec runs, since that typically blocks in main after initial setup. But that could be addressed by spawning a separate thread for each, and then creating utility functions to run various actions on either the Motif thread or the Qt thread. A very quick test of this (but running PyQt instead of c++ Qt) seems to work.

What else am I missing? I'm worried about more subtle issues that will either be intermittent or quickly prevent scalability.

I have a legacy application using Motif graphics that I am trying to migrate forward to modern times. Rewriting all at once is a hard-sell (and risky) so I'd like to slowly migrate one window at a time to Qt. Any given window would be wholly Qt or Motif.

One issue I can think of is where each app.exec runs, since that typically blocks in main after initial setup. But that could be addressed by spawning a separate thread for each, and then creating utility functions to run various actions on either the Motif thread or the Qt thread. A very quick test of this (but running PyQt instead of c++ Qt) seems to work.

What else am I missing? I'm worried about more subtle issues that will either be intermittent or quickly prevent scalability.

Share Improve this question asked 2 days ago ryan0270ryan0270 1,19712 silver badges35 bronze badges 5
  • "But that could be addressed by spawning a separate thread for each" - most GUI libraries I've worked with (including Qt) want very much to do all their rendering on the main thread. So this strikes me as kinda the wrong road to go down. – Jesper Juhl Commented 2 days ago
  • I wouldn't be surprised by this but I don't know any details. What is special about the main thread vs a spawned thread? – ryan0270 Commented 2 days ago
  • GUI elements must only be accessed from the main thread, or, to be precise, the thread in which the QApplication is created. It's also completely impossible to create a UI element in a thread different than that of the QApplication. Since it seems unlikely that the program has completely separated and not communicating windows or dialogs, what you propose is not doable to begin with, or inappropriate in principle. – musicamante Commented 2 days ago
  • @musicamante, can't the QApplication just be created on the spawned thread? (not doubting you, just trying to make sure I understand). You are correct that common information would be shared between both Motif and Qt windows, but there are already mechanisms for Qt GUIs to get data that originated on other threads. – ryan0270 Commented 2 days ago
  • can't the QApplication just be created on the spawned thread? Generally speaking NO. Qt was not tested nor designed to support it. It happens to work on Windows. It may work on some combinations of X libraries and X servers. It does not work on MacOS at all. But the deal is that you don't need to actually spin the QApplication event loop. In early Qt versions, all it does is spin the native X11 event loop under the covers. Because porting from Motif to Qt was an important use case back then, it paid for the development in part :) Qt was not multithread-aware back then. – Kuba hasn't fotten Monica Commented 2 days ago
Add a comment  | 

1 Answer 1

Reset to default 2

One of the ways Qt's early development was funded was, indeed, by customers doing incremental porting of Motif applications. You may find that an older Qt version - say version 2 or 3 - will work much better for that. First of all, earlier Qt doesn't do all that much more than Motif did, so it's less of an impedance mismatch. There should be some example code out there that shows how the event loops can be combined.

Of course, during porting all that stuff must be running on Linux using X11.

Once the initial port to Qt 2 or 3 is done, the code can be fairly easily ported to Qt 6. With some cleanups you'll end up with a code base that will at least compile using modern tools and do its job.

GUI frameworks that use event loops are typically not multi-threadable. All GUI stuff must be done from the single main thread, and that thread must be the only thread that uses the X11 library. X11 allows multithreading, but early Qt that coexisted with Motif was not designed to support that. It could be coerced to not crash, when multithreaded, but you were on your own.

A Qt GUI application doesn't need app.exec() in fact. It needs a QApplication object to exist, and a QEventLoop must have ran at least once in the main thread. Other than that, those early Qt versions will interoperate with motif event loop with not much trouble, and it won't even matter whether the event pump is running inside of QEventLoop or motif's equivalent. Under the covers they both spin the X11 event loop.

All of this breaks down rather badly once you go past Qt 3 AFAIK, since there was less demand for such ports later in Qt's life. So it's probably not really supported anymore, at least not officially. It may end up working though. I haven't checked.

If I was going to do it, I'd get a Qt 2 version running using the same C++ compiler as used to compile the motif application and go from there. I don't recall how much gain (or loss) in developer experience there was by going to Qt 3 for such a porting job. Perhaps not all that much.


Alternatively, use something like Cap'NProto, ZeroMQ, or ProtoBufs, and and split the UI across two processes. You want a higher level solution than just manually shuffling structs over the wire, because it becomes very painful once nested objects need to be sent. All the three frameworks I mentioned support serialization and deserialization of composite objects, strings, arrays, etc.

Once the UI is fully ported over, the remaining housekeeping Motif code can be removed, and the Qt UI can be moved back into the codebase of the original application.

发布评论

评论列表(0)

  1. 暂无评论