Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Audacity uses wxWidgets right now. We've been talking about migration to Qt 6 (and possibly QML for some things) but that would be a big re-platforming effort, still debating. Not sure if we can continue with wxWidgets and do a major UI/UX upgrade though


I have done it several time professionally (Motif, Qt3, GTK, etc, but not wx) to QtWidgets or QtQuick. It's been a while and I pivoted to other industries.

It's a potential project killer, but it can be done. The trick is to wrap all your objects in QObject classes. You keep the old UI code as-is as long as possible.

The first Jedi mind trick is to reverse the event loop. Qt supports GLib2 loops, but only as long as they are created by Qt. So you create a dummy QCoreApplication, start the event loop. Then you coerce GTK into using the glib event loop Qt created.

After that, you populate your QObjects I mentionned above. The `Q_PROPERTY` stuff is the important part. It *has* to be fully implemented for QML to ever work. For Qt5, you need to use Qt containers. This means porting your lists and other C++ types (or glib types) to Qt. For Qt6, I think you can get away with some of that, but not Qt5.

Then, make all the signals work. It is important that all properties have signals. The signals must be reliable. QML heavily relies on events for literally everything. Without events, your UX gets out of sync and crash.

The next part is models. Turn all list with selections to models. Don't try to render stuff using for-loops in QML, this is a terrible idea and will explode in your face. Qt Models are annoying to write (and get repetitive very fast), but reliable list models really greatly simplify the QML code.

When you have all those QObject to reflect your current codebase, you make a companion app. This is a small window (or LAN/Network smartphone UI using QtRemoteObjects).

Now you are ready for the UI. Add little features, one by one. Don't try to do everything at once. Again, as long as you can, keep the wx/GTK window alive and fully functional. Your app will look wierd with 1 wx window and 1 QtQuick window. However, having the fully functional old UI let you press buttons there and see the results being updated in QML. That let you polish/debug your signal/q_property code step by step.

Once you are "done" with your port, strip the UI code from the old codebase. Then refactor/clean the logic and turn it into a library. Then start merging your QObject shims and logic classes into a single class.

If you get there, congradulation, your port is complete. Time to annoy your users with a bunch of changes.


Thanks for the write-up! This is great, good to hear war stories. I've sent it to the devs - if they have any questions about the above, would it be possible to reach out for quick thoughts?


Same username on GitHub (public email there) and Reddit. I admit I am slowly losing the battle with my indox, so better ping on both. I would be glad to provide help where I can.


Love this! Although I will almost certainly never have reason to apply it. (Still good inspiration for any big rewrite, and I'm starting one pretty soon.)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: