Rewriting Qt in Rust
-
First of all, Qt is huge and most people will think of different things when talking about porting Qt (to Rust or anything else). I use QWidgets to compile for Windows, Linux, and macOS. Others mostly see the use of QML. Some think of Android and iOS when talking about Qt (because it can do that as well). Qt has also long been drifting away into automotive. Besides the pure GUI part of Qt there are many other modules like monetization, etc. Qt also is a full framework with classes for networking and file i/o.
From today's perspective it would be quite stupid to develop a library which does everything in the same way as Qt. Qt solved a lot of problems back in a time when there wasn't a good (enough) standard library. With version 6 Qt is moving closer to the STL. I would hope that the creators of Rust were smart enough that string, container, file and network classes are good enough that they don't need a Qt-port replacement.
It would be nice if Qt were to reinvent itself in C++. Today we got smart pointers. This could easily replace Qt's memory management solution using parenting. Common advice in modern C++ is to (almost) never use
new
which doesn't work with Qt. One of my main gripes with Qt is that all GUI programming must be funneled through a single thread (explicitly). This was fine back in the days when Qt was invented and computes only had a single core. In theory it would be easy to have a dedicated GUI thread running in the background and the programmer does not have to care to make GUI calls within that thread. Certainly, for performance reasons one should think this through for an optimal solution. I'm also annoyed that layout calculations are only done once the widget is shown. Even more annoying is using multiple monitors with different resolutions. I would hope that a modern UI kit would handle this properly in the background. I am even certain that it should be possible to make widget partly overlapping two screens having the right resolution/scaling on each of the two monitors. C++ also needs to evolve in a way that we can get rid ofmoc
. Hopefully, Rust has a solution for this already in place.Don't get me wrong: Qt is currently the best toolkit out there for the kind of software I write, but it is far from perfect or modern. Writing a GUI toolkit for Rust is a good idea and you can certainly borrow and learn from Qt. But, for a modern GUI toolkit you should certainly not port Qt to Rust. Design a new toolkit with modern ideas and modern solutions for modern problems.
-
I don't have any use for rust in the first place, so I see no value in it. IMHO, rust is another solution in search of a problem. Idle hands are deadly hands and when smart kids are bored they wreak havoc that has bad long term consequences.
Rust solves no problems for me. it just does things differently...the new cool way...
-
@Kent-Dorfman (Disclaimer: I haven't used Rust.) I do think that Rust solves one problem (from what I've heard): By default you don't have a problem with dangling pointers. Can anyone confirm that this main claim of Rust holds up? You can still explicitly write unsafe sections where you are allowed to shoot yourself into the foot. Probably a bad thing is that you can't use any C libraries if you want to stay on the safe side of the fence exclusively. That would be a major problem.
As long as this is the only problem that Rust solves, I agree that it is not worth switching. It has become very easy to write "safe" code in C++. I haven't had any problems with dangling pointers in new C++ code in years. As long as you use modern C++ and modern approaches (no non-owning raw pointers) you are quite safe. So, the only difference between C++ and Rust is that Rust is more explicit about this because it drops backwards compatibility. For C++, however, it comes back to programming style. Once modern C++ becomes a habit you will automatically avoid this kind of problem. Yes, C++ allows you to shoot yourself into the foot (as does Rust, but it makes it harder). If your habit tells you to keep the gun in the safe, accidents don't happen (unless you get out the gun).
Is there any other problem Rust solves compared to C++?
-
@SimonSchroeder As far as performance goes, Rust is both fast and memory-efficient: this is what I read.
-
@JoeCFD Rust, like C++, is a systems level language, so they are as fast and memory efficient as the user can make them to be. It doesn't have any inherent overhead like virtual machine, interpreter or garbage collected languages. I'd guess any differences with C++ would come down to compiler maturity, which I'd expect to be more or less converging by now. The backend is often shared anyway and sure, one or the other will come up wits some optimization in the frontend, but that's usually something that gets ported to other languages with time too. It's not like compiler guys are sleeping or not sharing.
Rust, learning from the past and not weighted down by legacy code, has better defaults than C++ e.g. move instead of copy by default, immutability by default and some memory management concepts like ownership or borrowing. Those are embedded in the language, where in C++ they've been added with time often in form of traits, new constructs or standard library additions. The value of Rust depends on how good or poor C++ you write, and can vary from game changing to insignificant.
IMO the memory problems in C++ come down mostly to poorly educated programmers that we see more and more. From what I observe the ChatGPT generation can shoot themselves in the foot even with a pillow, so if your company has this problem then switching to Rust might be beneficial (if you can actually manage to switch), but the more experienced professionals you have the faster cost/value perspective of switching is diminishing.
-
@Chris-Kawa Memory problems in C++ can be handled much better now than before. It may not a big deal anymore. Have not tried Rust and not sure how faster it is, for example in a sparse matrix solver.
-
in computer engineering there has been this never ending push to reduce the programmer alchemists to the importance of assembly line workers. I got into programming 40+ years ago because I wanted to be artsy and creative, not implement someones OCD directions for minimum wage.
college graduates aren't smart enough to understand the full software stack from physical hardware to business concept then obviously the system is flawed because that gives those who do understand it too much power. I have no use for languages that obfuscate the steps of abstraction from algorithm to electronic switch. If someone understands systems then they can effecitvely and safely program in C or C++ on those systems. Rust seems an attempt to cheapen the art.
-
@Kent-Dorfman said in Rewriting Qt in Rust:
there has been this never ending push to reduce the programmer alchemists to the importance of assembly line workers
Well, of course...why do you think they invented COBOL?
Historically, programmers have been known for being:
- necessary for IT (once IS) departments to function
- expensive/very expensive
- irreverent, sometimes to the point of flaky
Not a combination that endears one to the suits. It's only natural that people would try to obviate this. That they fail most of the time is a historical artifice, and won't keep them from trying.
-
This recent blog post made me think of this discussion :)
-
@Chris-Kawa You have some good points. Can you elaborate on the following:
Lets suppose we give the Rustaceans (pronounced as Rust-Asians) what they want and say that Rust is much better than C++ (23) for the sake of this post.
- Qt uses C++, not-free
- Slint uses Rust, free
- Flutter, free
Why should someone in 2023 still choose Qt with C++ in case of desktop and/or embedded devices over the others mentioned above?
You also said: "Qt also is a full framework with classes for networking and file i/o". However, in case of Linux there are enough C libraries that work on their own hence Qt classes for networking and file i/o aren't necessary.
Finally, one argument that Rustaceans state is that C++ has been trying to solve things by adding other things which complicates everything. What is your take on this?
Not choosing sides, as you are a very experienced programmer which can't be easily found nowadays I want to know your take on this.
-
Lets suppose we give the Rustaceans (pronounced as Rust-Asians) what they want and say that Rust is much better than C++ (23) for the sake of this post
Lets suppose sky turns red tomorrow... what's the point in questions like these? It's not happening soon and I'm really more interested in discussing real world problems and scenarios than hypotheticals. Maybe in couple of years (more like a decade) we can revisit the problem, but currently it's a pipe dream of the Rust people.
Qt uses C++, not-free
Huh? Qt is free, GPL or LGPL. That's how I've been using it for nearly 15 years.
Why should someone in 2023 still choose Qt with C++ in case of desktop and/or embedded devices over the others mentioned above?
I don't think anyone "should". I think they "can" consider it and it "might" turn out to be the best solution for them. It might not. I'm not gatekeeping anyone from making their own choices. Someone might already know C++ and/or Qt, so why switch and pay for the pain of re-learning everything from scratch for little to no benefit? Take me for example - I've been using C++ for most of my life at this point. I've been using Qt since 2008. I know they're not perfect, but I know most of the imperfections that affect me and have years of experience dealing with them. They rarely even bother me at this point and I barely register them when they come up. It's like marriage - sure you can switch for the new hotness, but is that really a long term win? ;) How much time and effort would it take me now to get to know Rust, Slint or any of the other to the same degree? What can I do in them that I can't in the technology I already know? What guarantee do I have that their imperfections wouldn't cause me more trouble than the ones I already know how to deal with? A bit of a sprinkle here and there, so I can join the cultists chanting over syntax? That's not nearly enough to even consider this. Sure, I take a look at them out of curiosity every now and then. I might write some toy program for personal use, but there's no value in seriously switching for me. More of a loss actually, because time and energy is something I have less and less with years.
hence Qt classes for networking and file i/o aren't necessary
Every operating system has a basic set of libraries that are building blocks for higher level libraries. With above mindset you don't need any non-OS provided libraries. Same for UI, be it Qt, Slint or Flutter. There are native APIs for UI after all. The point of all of those libraries is convenience layer over the usually low level and complicated native APIs. If you ever wrote
QWidget widget; widget.show();
and then tried to do equivalent in native API you will know the value of it. Same goes for networking, I/O or any other module. Not to mention the cross-platform nature of Qt.
I'm a low level guy, and sometimes seeing what Qt does underneath pains me, but it's usually a lot better anyway than what other frameworks do, like spinning up a web browser, javascript engine and taking up 1GB of RAM just to show a button on the screeen. So what if the API is written in a language with a bit easier syntax? Ugh... it's like they hate the idea of a battery lasting more than an hour, but I digress.Finally, one argument that Rustaceans state is that C++ has been trying to solve things by adding other things which complicates everything. What is your take on this?
It's complicated. C++ is a language on which a large chunk of the world's technology is built. It would be irresponsible to break compatibility for the sake of fixing little inconveniences that got into it over the years. Rust and other younger languages don't have that big of a legacy they need to care about. Most users of those are enthusiasts that don't mind rewriting large chunks of their software when the language changes something. This is prohibitively not true for most of the existing C++ code. So the reasonable approach is to improve the language by adding better facilities than breaking the old ones. Sure, this approach has caveats, making the overall language bigger and more complicated, but there's really no perfect solution to the legacy code issue in general.
Again, I'm not against new languages. I'm against fanboying/fangirling over them, mostly because of how annoying it is. Rust is not perfect and it bothers me when people try to paint it as such. These new things have their benefits, but also their downsides, like every technology. Legacy is a problem of C++ right now. Lack of reach, maturity and stability are just some of Rust's that I know of, even being a complete noob in it. I won't tell people which problem set to choose, but I would like to see more reason and consideration in people picking their solutions, instead of jumping on the new shiny, like a cat on a laser dot. Pick a hammer for a nail and an umbrella for rain. There's no omnitool (not counting the one from Mass Effect).
-
@Chris-Kawa said in Rewriting Qt in Rust:
The point of all of those libraries is convenience layer over the usually low level and complicated native APIs.
The main point of Qt is that its made by a company that sells APIs.
(granted, they are reaching out into services, which personally I hope will be a completely separate unit to avoid it taking away from Qt the libraries, but i digress).
Libraries you can sell to developers need to add value. And the fact that Qt has been around for so long shows that they do. Add value, that is.
The main benefit is one of cross-platform development. Its sooo much faster to write and test on your desktop and then simply deploy on mobile the exact same code. I don't want to even imagine using the Android native APIs. And then get myself a Mac to do the same thing again? Ugh, no.
Anyway, just ranting a little too.
I agree with all the C++ people in this thread. -
@TomZ said in Rewriting Qt in Rust:
The main point of Qt is that its made by a company that sells APIs.
The community can always fork from Qt under the GPL and LPGL. This way you can have Qt as full open source without a company behind it. Having a company putting in any money at all into an "open source" project is a good thing. I know that in reality the dynamics are a lot more complicated.
PS: There have been "forks" from Qt that want to be drop-in replacements in one sort or another:
https://www.copperspice.com
https://github.com/woboq/verdigris
If you haven't heard of those it makes the point for reality vs. the spirit of open source. The community seems to prefer Qt from a company over those two alternative solutions. -
@SimonSchroeder said in Rewriting Qt in Rust:
The community can always fork from Qt under the GPL and LPGL.
why would it?
@SimonSchroeder said in Rewriting Qt in Rust:
This way you can have Qt as full open source without a company behind it.
It already is full open source.
-
@TomZ said in Rewriting Qt in Rust:
why would it?
So that it is no longer tied to whatever TQtC do/don't do. @SimonSchroeder has given a couple of examples which already did this.
-
@SimonSchroeder said in Rewriting Qt in Rust:
One of my main gripes with Qt is that all GUI programming must be funneled through a single thread (explicitly).
Just had to comment to this one, as that made me laugh.
To be clear, this is just about the GUI classes, Qt itself does not in any way restrict you from using threads and off-loading work to worker threads. (Notice the QThreadPool class in QtCore).
Yes, indeed, you are obligated to manually route your GUI updates to the 'main' qt thread. The alternative would be massive locking infrastructure in the GUI framework or a massive amount of overhead of every function needing to move the update to the main thread for you behind the scenes.
You may not like it, but its the most commonly used solution for any generic set of (GUI) classes where the number of classes and methods is quite large.
It feels like you might just not have understood signals and QObject thread affinity if you think this is a problem, really.
Qt allows one of the most beautiful way of moving content from one thread to the other without any efforts on the side of the programmer.All you need to do is connect a queued connection between your data class and your GUI class. The
signals: void nameChanged(const QString&);
on one side and thepublic slots: void setName(const QString&)
on the other when connected will automatically be a queued connection if your data class (the emitting one) has a different thread affinity than the GUI one.
Nowhere have I seen such a simple way to allow you to introduce multi-threading to offload the hard work so it avoids blocking the GUI updating thread.Edit:
@SimonSchroeder said in Rewriting Qt in Rust:
I'm also annoyed that layout calculations are only done once the widget is shown. Even more annoying is using multiple monitors with different resolutions. I would hope that a modern UI kit would handle this properly in the background. I am even certain that it should be possible to make widget partly overlapping two screens having the right resolution/scaling on each of the two monitors.
Notice that those issues are not Qt issues, really.
They are issues in the graphics layer it builds on top of. The fact that the all graphics systems require the app to reserve a square for the window and draw into that, specifically.
Anything Qt could do would be a major hack and fail for a significant number of users.
-
@TomZ said in Rewriting Qt in Rust:
It feels like you might just not have understood signals and QObject thread affinity if you think this is a problem, really.
@SimonSchroeder understands Qt signals and thread affinity perfectly well! :) [Well I think so anyway!] His comment was what it was, i.e. Qt requires all UI accesses to be done in a single thread, which is a perfectly valid observation to make of as you will. As are your observations :)
-
@JonB said in Rewriting Qt in Rust:
Qt requires all UI accesses to be done in a single thread, which is a perfectly valid observation to make of as you will.
It is a valid observation, what is missing from that observation is what I replied with is that there is no clean alternative solution in any language or any framework known today.
This is a generic problem: how do you keep your stuff free from race-conditions if you have hundreds of classes and thousands of methods. For clarity, I'm JUST talking about the GUI stuff. Which is a small subjection of the whole.
If you find any framework of the size we are dealing with that solves it better, please share.
-
@SimonSchroeder said in Rewriting Qt in Rust:
@TomZ said in Rewriting Qt in Rust:
The main point of Qt is that its made by a company that sells APIs.
The community can always fork from Qt under the GPL and LPGL. This way you can have Qt as full open source without a company behind it. Having a company putting in any money at all into an "open source" project is a good thing. I know that in reality the dynamics are a lot more complicated.
PS: There have been "forks" from Qt that want to be drop-in replacements in one sort or another:
https://www.copperspice.com
https://github.com/woboq/verdigris
If you haven't heard of those it makes the point for reality vs. the spirit of open source. The community seems to prefer Qt from a company over those two alternative solutions.Just one thing: verdigris is not a fork at all, it's a header only library providing an alternative set of macros to define Qt objects as well as signals and slot in a way that is binary compatible with Qt, but does not require moc. You would use that with your standard Qt installation.
-
@TomZ
I just jumped to his defence. I modified my post a bit, don't want anybody to be down on anybody else!I don't know much about what other UIs/toolkits take as their approach. Purely OOI if one used, say, the Windows SDK to access a UI do you know what their requirement is if one uses threads [I do not know but am interested]?