Hacker News new | past | comments | ask | show | jobs | submit login
A Simple Rust GUI with QML (vandenoever.info)
182 points by irfanka on Feb 23, 2017 | hide | past | favorite | 53 comments



Because it has largely not been done before, part of me wonders how well Rust would work to build a large, complex GUI. All GUI code I've seen relies on inheritance and dynamic dispatch to structure APIs.

I would love to see something like the Flutter Engine[1] written in Rust, which is a layer tree that runs in an OpenGL context and includes text rendering, shape drawing, gesture recognition, scroll layers, a layout engine, etc. – all components necessary for modern mobile app development.

[1] https://github.com/flutter/engine


> All GUI code I've seen relies on inheritance and dynamic dispatch to structure APIs.

Rust has dynamic dispatch, by using trait objects (https://doc.rust-lang.org/book/trait-objects.html). It also has something similar to interface inheritance ("trait Foo: Bar" means that everything that implements the trait Foo must also implement the trait Bar), and one can always do "C-style inheritance" (have the parent be the first field of the child) for structs.

Given that, I'd say building a large, complex GUI framework in Rust is possible. I also wonder how a GUI framework written for Rust (instead of Rust bindings to a framework for another language) would look like.


> I would love to see something like the Flutter Engine[1] written in Rust, which is a layer tree that runs in an OpenGL context and includes text rendering, shape drawing, gesture recognition, scroll layers, a layout engine, etc. – all components necessary for modern mobile app development.

WebRender and Servo together contain all of these.


It would be genuinely exciting to see some of that tech being used for a Rust GUI library. Nobody seems to be working on that yet though, I don't think.


Right, but those components exist as bindings for HTML/CSS/JS. It would be awesome to see a Rust UI framework built on top of them.

It's certainly no coincidence that the top contributors to the Flutter engine are all Chromium contributors.


WebRender is not coupled in any way to HTML/CSS/JS as far as I know (I've used it in an app).

Fundamentally, it allows you to represent a scene-graph and render it efficiently. How you go about constructing and manipulating your scene graph is up to the application which uses it.

In Servo's case it parses HTML and CSS for structure and style and allows manipulations through JS through the DOM, but none of those are any concern for webrender.


I'd like to see rust bindings to the DOM. HTML and CSS are actually pretty good for representing UIs, the bottleneck is JS. I think it'd be interesting to build a desktop ui based on Servo.


I'd like to do this as well.

One of Servo's 2017 goals is to "Determine product opportunities for a standalone Servo browser or embeddable library." I'm following this very closely. I'd love to use a Rust equivalent of Electron in some projects.

I think Servo has much greater potential to be a viable high-end gaming platform than Firefox[0] (sans Quantum). HTML/CSS/JS UI with WebRender and some 3D rendering API which is not susceptible to bad GC pauses looks like the holy grail of game programming to me.

[0]: https://wiki.mozilla.org/Platform/Games



Oh wow, that's awesome. Will have to try it out.



Thanks for the link! I didn't know about Conrod, even though I knew about Piston. It looks very interesting – I will have to try it out.

also, the fact that it is one letter away from my name was confusing at first :P


QML has these. Also the properties/dataflow system is a really good way of building guis. Like react but much more terse and declarative.


It's not nearly as complex as that, but I can comment on a GUI program I've been developing for the last few months using the GTK bindings for rust [1]. I'm comparing rust today with C++/Qt as it was about 8 years ago, so bear that in mind in what follows. Before this project, the last big GUI I worked on was about 100k lines of C++, with a very intricate GUI involving both standard 2d components and quite a bit of animated OpenGL stuff. The program I'm working on now in rust is much smaller (about 20 different windows and dialogs, with various normal features along the lines of entry completion and search, and is about 5000 lines of code), but I think it's big enough that I have a feel for what it would be like to develop a big app in this environment.

After the initial bumps and scratches getting used to rust, I've found the experience to be better overall than I remember it being back in the day with C++ and Qt. I actually ended up implementing my own tiny version of signals and slots as I remembered them from Qt to handle interactions between the user and the stuff on the back end (mostly sqlite at this point). That in combination with a certain relaxed attitude about using Rc<RefCell<_>> for GUI stuff has put me in a place where I'm pretty confident that any normal GUI operation is pretty straightforward with rust.

The amount of boilerplate code seems pretty similar between the two. I think that a GUI framework specifically designed for rust might actually be a big win over other options here, but so far there isn't one that I know of that meets my needs. As it is, using the GTK components from rust is easier than using them from C (in my opinion), and comparable with my memory of using Qt in C++.

I've also found that the type system and the error handling are great compared to what I used before. They help not only in catching problems, but also in ensuring that the design is complete before I get too far into it. The code I'm writing now is much more reliable in terms of handling errors and covering corner cases than what I did back then in c++/qt. There is a price for this upfront in terms of aligning your mental model with what rust wants, especially if you're coming from the same background I was. Once that is done I don't think it's any more difficult to get stuff done here than it was there, and the results seem to be quite a bit more robust.

It wasn't all good times though - the initial unlearning/relearning curve was pretty rough for me. I've been programming professionally in various languages for about 15 years, and rust has taken longer for me to get comfortable with than any other language. That's including a wide variety of languages from various paradigms including constraint/logic programming (prolog and ciao), functional (lisp, ocaml, haskell, etc.), imperative (python,ruby,c/c++,javascript) and other more obscure ones. Something about the familiar features of algebraic data types, pattern matching, and type inference combined with the strict memory model caused a lot of mental interference that took me a long time to sort out.

The build system is actually one of the biggest reasons I stuck with rust through the pain of getting started. I really love cargo, to the point now that I can't stand the thought of going back to makefiles, cmake, or any other C++ build system I've tried. Cargo seems to just work, which means I spend less time fighting with obscure linker and compiler flags and more time getting things done. I'd put up with a lot from the language just to keep the build system, to be honest.

Overall developing a GUI app in rust has been a decent experience. If you're already comfortable with the language, I'd recommend spending the time to learn the GTK bindings. Once you internalize their basic operating scheme, the time required to get GUI stuff done with rust is comparable to other languages and toolkits, but you get the peculiar combination of benefits that come from using rust itself.

1. http://gtk-rs.org


Gist that I've been developing for quick setup guides (PRs welcome!): https://gist.github.com/ErichDonGubler/c802e066de7068241f0e6...

We're still trying to get this to work with Windows. I've been reporting on this issue here: https://github.com/White-Oak/qml-rust/issues/31.

Any suggestions to get this going would be appreciated! Developing with Rust/QML on Windows definitely seems possible at this point...that said, most of what's left to be defined is what setup is required to actually get things to work.


It was a bit of a struggle, but I was able to get this going for Mac w/Homebrew.

after `brew install qt5`, I had to `brew linkapps qt5` & `brew link --force qt5`. Then `ln -s /usr/local/opt/qt5/mkspecs /usr/local/mkspecs && ln -s /usr/local/opt/qt5/plugins /usr/local/plugins` which is super not ideal.

I had some error and ran `brew install doxygen --with-qt5` which may not be necessary, but after these steps it built.

Edit: scratch that. As soon as I try the example in main.rs, it fails to build again. 'ld: framework not found QtCore'


I also have cmake installed for Mac w/Homebrew and used a binary install of qt-5.8.

After adding the clang_64/bin dir on the $PATH I too am getting 'ld: framework not found QtCore'.

Anyone able to suggest where I'm going wrong?


BTW, the qt5 formula explicitly says it's keg-only because it "has CMake issues when linked".


Noticed that. Found some discussions about a possible bug in cmake or qt5 that were reported a month or two ago.


Part of me wonders how much better web programming could have been a decade ago if QT was the standard that browsers implemented, and we just shipped around QT frontends that ran sandboxed in the browser.


And instead of JS, we'd be stuck with C++. Not an improvement.

At least the frontend stack with the largest deployment—HTML, CSS, and JS—has a garbage collector and is memory safe. With C#/VB.NET on Windows, Swift on Mac/iOS, and Java on Android ascendant, this is now obviously the way to go. Imagine if we had permanently made the mistake of saddling the Web with manual, error-prone memory management.


Not true at all! Have you tried PyQT? It was in my experience an absolute pleasure to use, and I think satisfies your main criteria. No reason why there couldn't be similar bindings for any given language you prefer, though I understand the merits of standardizing on one.

But also the point is that the Qt runtime would be part of the browser, which is usually all C++ or Rust or whatever anyway - not the web programmer's responsibility.

What makes me sad is that Qt for a very long time has had a very well thought out ways of handling the complexities of UIs, including separating view from layout from business logic, doing layouts properly, they even have a pretty and lightweight DSL for defining UIs, which you can then style with a CSS-ish language. And a non-terrible UI builder on top of that. It even does responsive UIs these days! Granted, how well this would handle something as complex as current webapps is an interesting question, but they've always kept up with the changes, no problem.

Also they did proper threads and event loops, data storage and query APIs, serialization, networking and sockets, highly performant 2D and 3D graphics (GPU-accelerated stuff!), an embedded browser, and all this was (and is) all cross-platform! It really was miraculous magic that we had this circa 2005-2007, and it's frustrating to see bits and pieces of this just recently getting web standards. If in this day and age I see one more proposal for how to do javascript promises or Commonjs / AMD / ES6 modules or something I'm going to die of frustration and exhaustion. :-(


I'm paid (in part) to develop a GUI application with PyQt. It's excellent. Riverbank Computing deserves every penny. And QOpenGLWidget + PyQt is far and away the easiest way to get off the ground with modern OpenGL.


Theres some truth around it. While QML may be nice I found the total experience of the QT stack lacking. It's still required to do large parts of the application in C++, since QML is mainly the View part. The impedance mismatch between the c++ and QML parts is huge compared to an environment that only uses a single language. I was part of some embedded system projects that used Actionscript (Adobe AIR) for some former projects and moved to QT in newer ones. For me personally it felt like a step backwards, from being able to implement the whole application in a single language with reasonable properties into a split world where I still need to use native code with all it's downsides. I don't want to say Actionscript is great here (it's for me somewhere between plain ES5 JS and Typescript) - I would also prefer a uniform Java or C# experience (as available on Android or Windows platforms) compared to a mixed C++/QML setup.

I see the main proposition of QT/QML in providing a framework that is not tied to a particular platform. The main thing that comes close are browser engines, but many people will find their huge footprints too large for using them for embedded applications (or partly even standalone desktop apps).


> it felt like a step backwards, from being able to implement the whole application in a single language with reasonable properties into a split world where I still need to use native code with all it's downsides.

I see a clear benefit in separating the language for the UI from the application logic language. Having choice of the second is good. Otherwise you are limited a monolithic structure, and need to reinvent the way to define UI in each language.


Using a document description language for general application development is and remains INSANE.

The browser is an atrocious, non-sensical platform that was invented to display Hypertext, not to run apps. Now look what we got? 5 new JS frameworks per month, because of some minuscule, often fabricated productivity gain. Various competing improvements to make CSS somehow manageable and an untyped, arcane and hard to optimize language on top of it. And we still struggle to make decent looking and performing apps. It's stupid.


> Imagine if we had permanently made the mistake of saddling the Web with manual, error-prone memory management.

Sounds like WebAssembly :)


Which is why I'm glad that Web Assembly is offered in addition to a language with a garbage collector and a low learning curve.

(Note that, of course, I'm not opposed to wasm's existence: it's important for many use cases.)


You mean something like Douglas Crockford's seif https://news.ycombinator.com/item?id=11273630 project?


Quickly skipping through the thread, this definitely sounds like it! I'd not heard about this. It looks like this definitely addresses part of my concern around HTTP being suboptimal as an application delivery mechanism, not sure how Qt ties into this. I'll have to dive in further. Thank you!


I'm okay with the alternative.

HTML + CSS + JS are just barely not shitty, but have such widespread adoption and libraries. Web apps are just so easy to package and maintain.


Just in case, Rust integration of Sciter is even easier:

   extern crate sciter;

   fn main() {
      let mut frame = sciter::Window::new();
      frame.load_file("minimal.htm");
      frame.run_app();
   }
Result: https://camo.githubusercontent.com/b7d9438384930801ba15d027d...

Rust/Sciter integration: https://github.com/sciter-sdk/rust-sciter


Yeah but I feel like HTML GUIs are the antithesis of Rust. Granted, it may be the best option at the moment.


Why is it an antithesis?

HTML UI at the end is just a set of few simple concepts (at least with Sciter):

1. UI is a composition of just two universal components: Element and Node (text, comment, etc).

2. UI is a single rooted tree of such blocks - DOM tree.

3. The tree can be styled by well known CSS means.

4. Events are delivered to particular UI elements using bubbling/sinking event propagation schema.

5. Any DOM Element may have so called behavior assigned to it. The behavior is either native (C/C++/Rust/Go/etc) or script function. All <input> elements are normal DOM elements with corresponding behaviors attached.

I do not see how this simple setup can be an antithesis to anything.


Because Rust is all about efficiency and doing things 'the right way'. HTML is one massive hack at this point and one that wasn't even designed for making desktop GUIs. It's also really slow compared to true GUIs. Remember Firefox OS? Yeah.


How does it compare to https://github.com/cyndis/qmlrs ?


This project is "dead" for quite some time now. Don't know if they really restructure the project (this was the last active conversation i witnessed in the issues section https://github.com/cyndis/qmlrs/issues/28 ) or if its just abandoned now. currently i use this for playing around with rust + qml https://github.com/White-Oak/qml-rust this is the one used in the example, too


I'd prefer some real rust bindings instead of screwing around with qml.


What is it about Rust that makes porting QT different from any other language?


C++ is notoriously hard to bind. The only high-quality Qt bindings I know of are Python ones (Pyside).


shameless plug for my Go binding: https://github.com/therecipe/qt it's still WIP though


A recent one: Lisp (ECL) with QML integration: https://gitlab.com/eql/EQL5/wikis/home (see QML link: direct Lisp function calls from QML, examples of QML generation from Lisp).


How did PyQt manage to solve this problem?


PyQt has a whole other project, called sip, in service to it. If I understand it correctly, sip generates the bindings semi-automatically with a lot of special cases for Qt. Compared to the other set of Python C++ library bindings I've used (Vtk), they're magnificent.


Any tips you can give as far as starting to learn VTK, especially its Python bindings?


My experience is with maintaining somebody else's code, so I learned by cutting myself on its sharp edges. My advice is to avoid if possible. Unlike Qt, you can't subclass Vtk objects in Python. Which is a huge pain, because the Vtk design is heavily object-oriented. The autogenerated documentation is pretty unhelpful. It looks like this: http://www.vtk.org/doc/nightly/html/classvtkSliderWidget.htm.... Compare that with the magnificent Qt documentation: http://doc.qt.io/qt-5/qslider.html, and you'll see why I prefer working with Qt.


What about PyQt5? Or does it work differently?


PyQt5 does not seem to be maintained. The last couple of times I checked it, it was pretty dead: one maintainer with no time.


I think you have this backwards. PyQt5 is well maintained by a company that produces a GPL version and sells a commercially licensed version, which was Qt's original business model. Pyside was originally created by Nokia back when Nokia bought Qt, re-licensed it as LGPL, and needed LGPL python bindings. It's no longer maintained and only works with Qt4. Pyside 2 is a port of pyside to Qt 5 that seems to have some level of activity, but no releases..


Templatize the language, toolkit version and that could just about describe every binding of every c++ toolkit ever made.


I think the Qt Company is trying to revive pyside, but they have a lot of catching up to do. Not sure if they plan to do an update on their bindings generator (Shiboken) too, or start from scratch on that front.


Yes, I actually do have this backwards .. in more than one way ..:P

Sorry, I was thinking of Lua for Qt5 .. That was silly!

And, it is a pity about PySide, it was a neat project. :(


I prefer go-qml https://github.com/go-qml/qml

or PyQt




Consider applying for YC's Summer 2025 batch! Applications are open till May 13

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

Search: