Pre-implementation feedback for Qt with Rust

Oh no! I was actually already working on a Qt binding sometime during summer.

I got singals & slots partially working via lambdas - it's possible in my code to connect existing signals to lambdas, but not define own signals, but that should also be possible the same way QML does it.
I got subclassing basically working as well via trait objects.
I also had some preliminary support for function overloadign too, via tuples+traits.

I generated the binding dynamically from Qt Doc metadata.

Cool. Maybe you have so idea on the work going on over here then :slight_smile: https://github.com/rust-qt/cpp_to_rust I'm sure that @Riateche would like the input as well :slight_smile:

They seem to be much farther along, although they might benefit from my subclassing imeplemetation. I'll have a look...

Inheritance is really necessary in Qt. You just can't do certain things without it. I've got a plan for it too, though.

I don't like the idea of messing with moc. I think I can make all signal/slot magic work on C++ side where moc is working in a regular fashion. Something like generating a QObject subclass with signals and slots of every possible argument types and allowing to inherit that type in Rust. I'll sum it up in the issue tracker soon.

I've just got from the nightmare of making the project work on MSVC. I wasn't expecting to have so much trouble, but now it seems to work at last. I'll set up Appveyor and then I'll be able to move on to more pleasant things.

Parsing Qt Doc metadata... I was on that road early in my project. But it turns out Qt doc is not as good as it seems. It has a lot of inaccuracy and it lacks some crucial information, such as template arguments.

1 Like

If we could avoid using Moc (but still have similar functionality) I'm all for that.

That's pretty much what I've done. You want to see the code?

I made a simple example of using rustcxx and Qt's QML that supports signals and slots:

Yes, it will be interesting to see the code. I think I will review all existing implementations and try to get the best from each of them.

1 Like

I've written my plans about signals and slots here:

https://github.com/rust-qt/cpp_to_rust/issues/7#issuecomment-249437950

Noticed! Going to read in details. Thanks!

My daily job is actually working with Qt(components like a CacheManager) and on Qt(the code itself - we deliver it to other projects) - so I might be able to help here.
I will look in the weekend on all the mentioned implementations and maybe give some feedback.
moc is not that awful(and for signal/slots you basically need to implement moc for Rust), you could get some inspiration from it or from Verdigris(same developer).

One way to make it easier would be to "start" the Rust code from within Qt because of the Event Loop(QCoreApplication and in general every QThread has its own Event Loop, without it you can't have signal/slots).

To be sincere though, the only thing I am interested from Qt is QML. The rest is available in the Rust ecosystem(maybe not all, although I cannot think of the top of my head what is missing except for the GUI stuff, Qt Service Framework and the State Machine Framework). The nice thing with Rust though is that the dependencies are A Lot smaller. Although, Qt now can get a little bit smaller too.

For perspective, I'd like to provide a counterpoint to your QML comment.

There are two things I'm interested in when I look at ways to use Rust with Qt:

  1. Offloading as much of my "risk burnout by writing automated tests" to Rust's type system as possible. (The C++ API is more valuable to me than QML on this front)

  2. Making portable GUIs that fit into my desktop as natively as possible. (Last I checked, QML's support for native widgets was still too immature to be acceptable)

Because the latter is non-negotiable and the former isn't very negotiable either, I've been sticking with PyQt for my GUI applications since it wraps the C++ side of the APIs while still giving me "abort the signal handler with a traceback and let the event loop keep spinning instead of segfaulting" behaviour as the best available runner-up to a good, solid Rust API.

Qt is one of the best libraries for GUI. Rust needs a good GUI library, and it doesn't look like someone is going to write a Rust library as good as Qt any time soon. So there is no choice but to wrap Qt. Some parts of Qt are not all that interesting, like QtNetwork. But they are convenient because they integrate with Qt's types, event loop, etc. So I'm going to wrap all of them.

There is already a QML wrapper for Rust. But I don't see how QML can replace other parts of Qt.

It's not just about quality. It's also that I insist that my applications have a consistent look and feel.

Qt, GTK+ 2.x, and GTK+ 3.x are the only mainstream toolkits for a Linux desktop which people aim to unify theming across, so it has to be one of those.

GTK+ 2.x is a legacy solution on life support, so that's not an option.

GTK+ 3.x has a whole host of problems:

  • Unstable theming APIs driving away developers of themes I like and limiting QGnomePlatform to themes which have been manually ported from GTK+ to Qt (unlike QGtkStyle).
  • Buggy, regression-prone support for hiding GNOME-isms outside GNOME 3 (If I open a GTK+ 3.x app on my desktop, it'll show the traditional and unified "for putting a menu button in the titlebar" menu bars simultaneously)
  • Gleefully embracing UX decisions which defy decades of HCI research (like putting action buttons in the titlebar "because wasted space" rather than letting natural reading flow place them in the "end of last line on page" corner)

By process of elimination, even if it were inferior, I'd sooner wrap Qt in a nicer API than use GTK+ 3.x.

but EFL would be the much more rust compatibe/friendly solution IMHO.

Ok, here's my bits: https://github.com/vojtechkral/qrust

I think the downside of my approach is a lot of glue code.

Example usage is in the wip subdirectory, but be warned, it's quite messy. There is no high-level binding for QApplication, so I just hacked that one temporarily. But it has a subclass of QWidget in Rust :slight_smile:

Theming aside, I think I'd trust PyQt to help me write good, reliable code more than any bindings for EFL.

If even half of that WTF post is to be believed, the Enlightenment project has a deep and systemic problem that's directly at odds with the Rust ecosystem's philosophy for producing reliable libraries and applications.

From quickly grepping through the source code, I'd say a quart is true. You really get "spanked" if you mess with internals which you can only really mess with by wildly memseting around and of that quart a lot is just a "little" inaccurate.

That post is also two years old already, which is a lot in internet time.

I for myself would like to see a wrapper around EFL, which then could incorporate type safety and eliminate the shortcomings of EFL, but I would prefer to see Qt first.

Here it is why I am interested mostly only in QML:
http://doc-snapshots.qt.io/qt5-5.8/qtquickcontrols2-texteditor-example.html

This is Qt Quick Controls 2.1 from Qt 5.8(soon to be released).
In a few simple lines of code you have:

  • Beatiful UI
  • The UI is GPU accelerated(animations...)
  • Cross-platform and works with different display servers, working on Wayland, X11, Android, Windows, macOS, iOS...
  • Supports OpenGL, Software Raster, DirectX, Vulkan(experimental) - all automatically selected for you based on the platform and support.
    For example, on Windows, if you want, you can use OpenGL and if the Windows environment doesn't have good drivers and support only OpenGL 1.1, your application will still run since Qt will transparently use Google's Angle and convert on-the-fly calls to OpenGL(ES) into DirectX.
    On Linux, if you have issues with the drivers, it can automatically fall-back to the Software Raster.
  • Great support for animations(you get some by default, using those components).
  • Theming
  • Native support for HighDPI
  • Native support for multi-screen(of course, taken care to do it right on every one of those display servers)
  • Good API

We already have in Rust libraries that replace most of the modules available in Qt.
But we do not have something like QML, which would take years and years to achieve this maturity and feature set.

I don't really focusing on Rust+QML as having a good value proposition. If you want that kind of UI, there are already plenty of options, including writing everything in Rust or QML except a thin C++ binding layer.

When I look at that, I see:

  1. Three themes (Default, Material, and Universal) which are all that godawful "flat design" trend Windows 8 pioneered. (Flat design is for non-interactive things like documents, not UIs. In the context of UIs, flat design is a footgun at best.)
  2. A default set of controls disjoint from the set of C++ controls and erring on the side of mobile which I'd either gain no benefit from or have to spend extra effort working around in order to make desktop utilities or high-density data management applications.
  3. No "Pre-Built Native Styles" in contrast to Qt Quick Controls 1 (this is non-negotiable for me)
  4. Intentionally retiring Controls 1's QAction analogue and directing people to its QShortcut analogue. (I'm migrating away from GTK+. I don't want to have to reinvent QAction just because "the future is mobile" and, therefore, desktop OSes are a dead end.)
  5. Retiring SplitView, TreeView, and TableView... no replacement listed on the comparison chart.
  6. Inline callbacks written in a JavaScript-derived language which can't be disabled to force direct reference to compile-time-checked functions.

All in all, Quick Controls 2 just further cements my view that the world has gone crazy and it's the new fad to throw out and spit on decades of HCI research... but then I guess I shouldn't be surprised. It seems like every generation needs to rediscover/reinvent everything else accessible enough to make a college/university education optional. Why should this be any different?

1 Like