Current state of GUI development in Rust?


#1

I’m a die-hard linux fan and often when I need to make a program I’ll just build a command-line program, however if you want to share your awesome program with end users (i.e. non-programmers, typically on Windows) or customers, people expect a GUI.

I’ve dabbled with gtk-rs in the past, but never made anything more complex than a gui with a button and a couple text fields, so I’m wondering what is story for Rust on the desktop like at the moment?

In Particular:

  • Is it possible to create larger, more complex GUI programs in Rust using bindings to existing GUI toolkits (e.g. Qt)?
  • Can you make cross-platform (e.g. Windows, Linux, and Mac) Rust GUI programs?
  • If you’ve ever tried to make a GUI program in Rust, what were your experiences and do you have any recommendations for others?
  • Are there good alternatives to qt and gtk for making GUI programs?

I’m aware that both qml-rust and qmlrs exist, but with only 100-odd commits each I’m a bit skeptical that they are going to be very robust, documented (tutorials, API docs, blog posts, etc), or well maintained.


Best GUI for Rust?
#2

I can’t answer your questions, but I would like to bring relm to your attention. It’s a new crate that aims to simplify GUI development in Rust by providing a rustic wrapper around GTK.


#3

Also see conrod.


#4

Relm looks quite promising. I’ll have to look through its examples and do a bit of research on how Elm does things.

I know a big issue with most GUI toolkits is that you often have lots of shared mutable pointers all over the place. For example, child widgets often have a pointer back to their parent and the parent has a pointer to the child. Rust isn’t a big fan of this, so I’m expecting bindings to toolkits like gtk and qt to not be very ergonomic and have Rc<RefCell<T>> everywhere.

I thought about using conrod for a small program, but the Getting Started Guide just bounce you over to the examples, and then expect you to be able to make sense of a massive wall of code without explaining how anything works :disappointed:


#5

There are SDL bindings and other low level libraries if you want more than a toolkit offers.

Writing a HTML/JavaScript GUI may also be an option. Linking to back-end server libraries e.g. https://rocket.rs/

To add to the list;

  • webasm/asmjs are in basic working condition, would have to write a fair bit to get a working interactive canvas gui.
  • OS with GUI has been written in rust https://www.redox-os.org/

#6

I can point you to my attempt to describe how conrod works through a simple example here, but I haven’t got much time next to my studies to keep up with recent conrod versions. ( and I’m not that good at rust at all…)


Idea: Use servo as a gui toolkit
#7

This is what I perceive …

There seems to be a dilemna e.g. GUIs tend to be very language specific, and if your focus is heavily around a specific library or framework, you’re always going to have an easier time using the language of that framework (e.g. use Swift to use Apple’s GUI, use Java for android apps, use C++ for Qt, etc etc)

In many ways, GUIs drove the languages, not vica versa (e.g. that is why OOP became popular - C++/MFC->C#, Objective-C/NeXT/Apple->Swift). Rust’s choices are focussed on a different use case.

Using wrappers to other languages to me is always slightly unsatisfactory, i.e. you run into a point where the library itself is not built around the language’s specfic concepts (e.g. rust seems quite similar to C++, but even superficially introduces interface problems with a completely different system for naming things)

Do you think it is feasible for the Rust community to get to the point where people really can use something natively Rust from the ground up ? (and have that option taken seriously)

it seems with Servo being a driving use case (web browsers are basically a huge online gui, right), this should be feasible? And of course I note the option of ‘web interface’ mentioned above, and of course writing something web connected absolutely is a rust use-case.


#8

From what I’ve seen of the overall software ecosystem so far, I very much like this answer. Rust was designed to be more of a general programming language, replacing a lot of the things you’d typically use Python or C++ for, instead of being driven by a particular GUI (Swift) or web (Ruby) framework .

Rust is already being used for web servers, so it is quite feasible that you can use a web UI instead of a traditional desktop app. This also benefits from cross-platform out of the box, thousands of existing JS and CSS frameworks for the front end, and loads of information on the internet for making a web UI backed by a server.

I reckon something like Rocket + React would work quite well, plus it gives you a nice separation of concerns that GUI programs tend to lack. I’ve seen my fair share of GUI programs where the front-end logic and application logic is one tightly coupled ball of spaghetti. Web apps with a server-client model tend to not have that problem.

I’m not sure to be honest, Rust can easily interoperate with C so creating a pure-Rust toolkit which binds to the Windows windowing API is technically feasible. Likewise, there are already crates which can communicate with Wayland or X on Linux. There are also some nice solutions like Conrod built entirely Rust in Rust, plus libraries like Relm fit Rust’s feel a lot more idiomatic than all the other GUI toolkit bindings I’ve tried so far.

Whether any of these really take off though, that’s an entirely different question.


#9

[quote=“Michael-F-Bryan, post:8, topic:11643”]There are also some nice solutions like Conrod built entirely Rust in Rust, plus libraries like Relm fit Rust’s feel a lot more idiomatic
[/quote]

yes that’s what I’ve really got in mind. I haven’t looked any of these detail, but I know (a) rust is missing the inheritance which does actually work ok for guis (‘this derived control = that one with these overrides’) … but (b) somewhere between it’s trait-objects, decent Lambda syntax and Macro system … it should be possible to build something nice ? I know in C++ the frustration is with a lack of reflection (various workarounds for ‘data-exchange’ and serialization) … I figure rusts macros should allow declaring, say, ‘a data structure which rolls it’s bindings to a user-interface’

Perhaps that the best ‘21st century’ answer; The OP really has the classic desktop-app in mind… but if the goal is “to share your awesome program with end users” - a web interface achieves that end result


#10

For the state of Qt you may want to check out this thread Rust-Qt alpha release and feedback request


#11

It would be nice if one day it could work with Qt backend. I understand GTK is easier to bind, because it is designed for it much better, but only Qt works on all mobile platforms.


#12

This does not apply to Gtk+. Gtk+ is very portable to other languages, e.g. python, perl, vala, JavaScript. It is less portable to other platforms, with some glitches even on Windows.


#13

Here are two more GUI libraries in Rust that wrap existing UI toolkits in more Rustic APIs:


#14

Well cross platform/cross language gui is certainly possible, but there’s the sliding scale of quality and friction.

I see python/perl/javascript as ‘extention languages’/‘scripting languages’ (whatever you want to call it) controlling some underlying engine;

Gtk itself from what I know has a very low level C API , as such it benefits from creating a different wrapper. Something like the cocoa frameworks on apple on the other hand are designed to be used directly; using ‘raw Gtk in C’ and using the apple frameworks in Swift… very different levels.

vala …not familiar with it but isn’t this basically created by the Gtk guys as something to use Gtk ('vala is to Gtk , as swift is to cocoa).

what I see is a middle ground between the systems languages and the ‘scripting languages’ … the ‘application languages’ (c#,swift etc) which have essentially been designed in tandem with or around some sort of existing toolkit…

  • ‘here’s our frameworks, whats the language we need to use them more elegantly?’

  • ‘ok, lets build the ideal application language… then build the framework that emerges from it’.

Whilst rust may be able to bind to something else… what it needs IMO is something built around the strengths of it’s own unique features (leverage the macros, enums, and traits; avoid the lack of inheritance ,default params, overloading).


#15

I think that conrod is the best solution here, but it could do with some TLC to make it easier to use, and perhaps provide some more widgets out of the box.

Having done quite a lot of web programming over the years, using React for the first time was an absolute revelation to me: suddenly I didn’t have random bits of state all over the place, I just had my single redux store, and any state updates were predictable and reliable.

Conrod attempts to mirror this approach in desktop gui design. It has an internal diff algorithm, so you can redraw the whole app every tick, and conrod will only update widgets as needed.

What conrod needs IMHO is more help getting up to speed, with some more examples, specifically something like TodoMVC would help people, who are familiar with that example. Note to self: actually do this if you have time :slight_smile:


#16

That’s interesting. I would not have thought that given the OP’s description that Conrod would be applicable. However, perhaps I’ve just had a misunderstanding of their scope based on the fact that it’s under Piston and renders into OpenGL as opposed to a Qt or GTK or native backend; and thus doesn’t automatically support, e.g., Accessibility which is mandated for government, educational, and many business institutions. In any case, I’ve opened up an issue asking about the scope given that Conrod seems to be often mentioned in a wider context.


#17

That’s interesting about accessibility, I’ve only ever dealt with that in html, and don’t know about how screen readers interact with gui toolkits.


#18

OP here! I’ve dabbled with conrod in the past, but found it hard to use because it’s so young and the getting started guide is incomplete. At the moment it only tells you how you can install rust and how to run the examples. In particular the “Let’s Create a GUI” chapter (which I would argue is probably the most important bit in the entire guide) is still yet to be written, and that makes it really hard to figure out how to use the library.

The examples are also not exactly what I’d call realistic/idiomatic which makes it hard to understand how to make a GUI program which can scale to more than a couple hundred lines without turning into a code monster. It feels like everything is shoved into a single 100+ line main() function, with high level logic and low level logic right next to each other, which you’d never see in any non-trivial GUI.

I know I probably sound quite negative, but the only thing stopping conrod from being a GUI toolkit I’d recommend to others is the lack of documentation and examples which are representative of real-world use.

So I guess I’m mirroring @derekdreery here in saying:

If I get time I’ll see if I can make a PR to work on the next chapter of the getting started guide. There’s a 11-month old PR for the next chapter, but I think it may have been forgotten…


#19

I’m currently thinking about creating a “native” app that uses Rocket as a server, which serves basically a web app built on VueJS. This web app is opened in the browser, like any other. All state other than GUI state is managed in the rocket server.

Advantages: cross platform, single binary, efficient, built to purpose, no cross-platform issues from Qt, GTK, or other GUI toolkit hopefuls
Disadvantages: HTML is a relatively fidgety way to define a GUI, there is no server optimization a la Apache or even Nginx, new build target needed for each supported platform


#20

It would make more sense to do this with Electron then, IMO. (if it’s really only supposed to be native)

And if you really want to use Rust you can use https://guides.neon-bindings.com/hello-world/ to write your business logic in Rust.

But then again, what’s the point of using something like Rust if you end up with the bloated Electron + JS stack again…