PyQt5 Tutorial: Create a Python GUI in 2018
build-system.fman.io
build-system.fman.io
For our use case, relative speed of the GUI isn't a factor. We've considered moving to electron just for ease of development, but python is winning out.
Measuring memory use is difficult.
Perhaps there's some API to call instead.
Felt exactly like making a RQT plugin.
Evidence? I think you're making a great point (about the reputation of html/css/js) but leave the unfounded claims out and your point would be stronger.
Does anyone know if there's any good shim/wrapper around PyQt that has a better API?
Having used much worse Python bindings for other C++ libraries, the degree to which PyQt just works without blowing up in your face is itself pretty astonishing. Add to that the maturity and depth of the Qt Widget library, and the result is a real pleasure to use.
Knowing some of my coworkers, though (who use Python daily), I can understand why it'd be jarring.
> And the fact the label magically attaches to the app through some side effect is also confusing.
Are you referring to the first "label.show()" example?
Typically that pattern is rare (~once per app for the main window). Regarding attachment to the app; QApplication is a process-wide singleton. All objects belong to the same app.
If possible, I would rather get behind the "official" one since we also already pay for commercial Qt licenses.
E.g. this works in PyQt:
def f(): pass
signal.connect(f)
signal.disconnect(f)
But the disconnect fails in PySide2 (RuntimError: not connected). Seems like you have to store the connection object, which is a bit of a PITA because signal.connect() does not return that.Some of the examples in the documentation are still in C++, but it's pretty easy to translate them to Python since the names are the same. (Sometimes painfully so, e.g PySide2.QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOff.)
If you do anything serious with Qt you'll have to read those anyway, I believe even PyQt stopped "translating" the docs to python. It's easy enough anyway, even for people like me with no real experience of C++.
That I have to choose between C++ or Python makes it very difficult for many use cases in other languages. What essentially ends up happening is you create the UI in C++ then build a communication/bridge layer with your Go/Rust/JVM/etc app via C and the respective language's FFI features.
https://github.com/qmlnet/qmlnet
It worked out nicely.
Even Dropbox had to rewrite their packaging to ensure maximum system compatibility (https://news.ycombinator.com/item?id=18067784)
2. QML is an amazing language. It is modern, declarative and reactive but still very simple to use. Personally I don't want to go back to the traditional GUI coding styles after experienced QML.
3. Qt Designer is a great GUI tool that you can quickly prototype a GUI app.
4. Qt has the best documentation among cross-platform GUI frameworks.
5. Qt is a much bigger framework having more features. For example, you can easily embed WebKit or Chromium very easily.
To join in this comment thread's Electron-ragging, I often find it frustrating that the hard-won OS idioms of the last 20 years have been left so easy to jettison in the age of apps.
QT is basically one of two toolkits that most Linux desktops are built on: it has to be wide-ranging enough to cover everything a desktop does, be accessible, and it has to interoperate with "the other" toolkit (GTK). It's absolutely nothing like Electron.
1: https://fman.io/blog/picking-technologies-for-a-desktop-app-...
Dumb question time: Is this also usable with QML?
"In the Python world, the process of turning source code into a self-contained executable is called freezing. Although there are many libraries that address this issue – such as PyInstaller, py2exe, cx_Freeze, bbfreze, py2app, ... – freezing PyQt apps has traditionally been a surprisingly hard problem.
We will use a new library called fbs..."
click to fbs...
"You can use fbs for free in open source projects that are licensed under the GPL. If you don't want to open your code up to the public, you can purchase a commercial license for EUR 249 per developer"
I'd happily pay the 250 euros but I somehow doubt fbs will also convert my code to C and compile it.
It's robust, proven, does work well with C extensions (including numpy and QT) and produces stand alone binaries. You can produce binaries for Windows, Linux and Mac (but not cross compile). It works by turning the whole Python code into C before compiling the result. The additional benefit of that is that you gain a bit of execution speed.
The project is amazingly little known in the community while PyInstaller, py2exe, cx_Freeze, bbfreze, py2app are: nuikta works better, handle more edge cases, target more OSes and support recent versions of Python.
The best way to be convinced is to read the last entry of the blog on the home page: the guy is meticulous with this project.
PyInstaller felt quite close to an auto-unzipping python interpreter and your code, simple.
The problems with packaging PyQt usually boil down to module discovery, because the import machinery is leveraged by the wrapper in nontrivial ways. PyInstaller has been ok for me recently, whereas cx_freeze was unpredictable across minor versions.
I wonder what fbs does in this case that handles the PyQt import stuff so well.
Do you use any particular lib for your cythonization, or is it all custom ?
At work we use Qt5 with both C++ and Python (through PyQt) and I love it.
The model/view components scale to ~infty items, if the model is correctly implemented. They also support lazy loading.
https://github.com/qmlnet/qmlnet
It is a perfect balance between QML and .NET. The tech stack splits along the perfect line. QML for UI, .NET for business logic.
I'd be glad to answer any questions.
If you need some help with PyQt development, call me up, I'm cheap ;)
You can't. Also keep in mind that Python's thread-local storage only works with the threading module threads, not Python threads created elsewhere (e.g. by the "outer" C++ application itself or by a QThread wrapper). It's really quite poorly implemented there IMHO.
Well, for one reason, the choice for Python (or the implementation we now call CPython) was made when you couldn't get what you think of as "real threads" in C/C++, and Java and C# did not yet exist.
Like many engineering choices, there are tradeoffs. The choice to implement Python memory management with reference counting and thus a global interpreter lock was made in an era when garbage collection was much less advanced, when most C libraries were not thread safe, and multi-core CPUs were mainly large computer installations.
As the stack overflow post https://softwareengineering.stackexchange.com/questions/1868... describes, there are advantages to an interpreter lock.
Now you know why.
But the world has changed in ways that make the disadvantages much more prominent. Unfortunately, efforts to remove it have failed because they slow down single-thread performance (which remains quite important) or break backward compatibility, etc.
Note that the "threading" and "_threading" modules wrap thread creation and otherwise just use interpreter C APIs. Their design flaw is that they assume that they are the only ones using the interpreter API.
The Linux side was surprisingly painless, but getting the Windows side going was a nightmare; none of the traditional options for creating a standalone Windows executable actually worked, and I ended up resorting to installing MSYS2 on every machine, then packaging the app for MSYS2 (and pulling in all of Qt5 as a dependency, meaning that it takes up multiple gigabytes of space for what should be a pretty simple desktop app).
I didn't know about fbs. I'm gonna try it out tonight. The fact that it seems to require resulting apps to be under the GPL is unfortunate, but that's already the case for PyQt5, so whatever.
export QT_AUTO_SCREEN_SCALE_FACTOR=1
for auto scaling. See: https://blog.qt.io/blog/2016/01/26/high-dpi-support-in-qt-5-... and https://wiki.archlinux.org/index.php/HiDPI#Qt_5 for more options and other UI kits.
Normally, the desktop environment should do this for you, though. But yeah, this was quite horrible for me for a long time and only got better recently (~ 1 to 2 years), with an wider adoption of high DPI screens, I'd guess.
Pyside/"Qt for Python" is LGPL.
You then need a license for QT, which is LGPL or commercial. You can use the LGPL version of Qt with commercial PyQt, but I never understood the hoops you might have to jump through in order to comply with the LGPL. Packaging python apps is painful enough without having to worry about that, might as well spend a little to avoid the aggravation. LGPL Qt also lacks a few advanced packages.
Do note that the PyQt5 authors (Riverbank Computing) have made it explicit that their view of GPL linking (a matter of debate in some circles) is that you can use PyQt5 from MIT/BSD/... applications.
1) I like how GTK and Python object lifetime tracking are compatible (both are simply reference counted), where as Qt has this hierarchical model that feels weird in Python and that led to random segfaults when I tried using PyQt for a serious project last year.
2) gobject introspection works with a variety of different bindings and libraries and provides an object model extensible in any language. Last time I looked at Qt bindings, they looked more like pre-gobject-introspection Python GTK bindings, meaning they were fixed-function and frequently left out some functionality. With gobject, all language bindings are first-class citizens.
Do they get collected properly, like they would with pure Python objects, or would you have to break up the cycle?
Because GTK is awful outside of Linux.
I'm pretty sure you can. I like them in most cases, though, just wish they'd gone the Windows/MacOS way of slowly intruding/overlapping a bit occasionally instead of reinventing the whole bar.
Qt looks at least a magnitude better (more native) on those platforms
note that this theme is generally not used anymore, being superseded by the WindowsVista one which uses native theming info from windows to render the widgets.
Why not? For an app to feel fast, you need to make it responsive and non-blocking. You can easily make apps with Python and Qt or Gtk that start instantly and never seem to hang. Discipline when it comes to not running things on the main thread, using proper async techniques etc. is more important than the number crunching ability of your programming language.
And when you need raw speed, you can easily drop in some C++ code with SWIG for example. For example, I made a GUI for controlling an experimental sensor system. The GUI could look boring, but should be rock solid and always responsive, it should be easy to add new features, and it had to read data from PCIe at hundreds of MB/s or even faster. So I wrote the GUI in PyQt, the PCIe part in C++. Python allowed me to mock the hardware code out easily so I could test the GUI separately, and made it really easy to read configuration files etc. which is unneccessary painful in C++.
I work on a data visualization program written with PyQt. As an example, in a scatterplot with several hundred thousand rows, the bottleneck is not number crunching. Numpy could go up another order of magnitude. Probably two. The bottleneck is figuring out efficient ways to display all of the points, correctly, and make them pickable.
Interesting!
* https://assets.guitar-pro.com/1.3/images/www/guitar-pro-7/ca...
* https://www.awn.com/sites/default/files/styles/original/publ...
* http://www.comptoir-hardware.com/images/stories/_software/am...
it's not what I use myself, being more of an i3/terminal guy, but it's absolutely what the clients want
I'm sure someone (and, in particular, their designers) think they look nice. But the thing about looks is that they're very subjective. However, if I'm using some OS/desktop combo, that means I find its UI, at the very least, acceptable. And thus any app that uses native UI look & feel on that platform is also acceptable. I can't say that for many custom-themed apps.
For example, out of your links, I would say that 2 are downright ugly, and the third is tolerable. And I'm not sure what "in 2018" has to do with that.
PyQt uses compiled Qt C++ code so isn't really that slow, comparable to how NumPy does it's number crunching. Even if you do find it is slow, you can always come back and branch down to the C++ level when needed, although there are ton of steps you could take to optimize in Python first. There are also all the Qt tools from UI editor and Designer to QML and way more if you really wanna go down the rabbit hole...
What are you suggesting as a really good looking and fast cross platform alternative??
1: https://stackoverflow.com/a/1094530/1839209
2: https://www.reddit.com/r/learnpython/comments/108zfq/tk_or_q...
3: https://www.quora.com/Should-I-use-PyQt-GTK3-or-tkinter-for-...
Qt widgets look close to native UIs but the feel isn't always the same, especially when you have to juggle with different platforms (all native widgets differ in subtle ways even when their function is the same).
(If you're on Windows. On Linux, Qt could be considered native. On Mac there is PyObjC. )
> why are you using Python?
I'm not sure
> Platform-native APIs.
are a replacement for Python?
* http://blog.qt.io/blog/2017/07/05/qt-quick-designer-coffee-m...
* http://blog.qt.io/blog/2017/05/24/qt-quick-designer-qt-creat...
If you use the PyQT-provided wheels and/or you don'want to mess with the whole Qt, then you can separately install QtCreator, which is very simple and embeds QtDesigner.
Also - layouts in VB/Delphi weren't responsive, layouts made in QtDesigner are.
Once customer bought new monitors and we had to "upgrade" all forms from 800x600 to 1024x768. Took us 3 months. Qt forms worked fine out of the box.
I try hard to do that (it saves on boilerplate), but the challenge is always in finding signals and slots with the same precise amount of parameters. Say I trigger a signal with no parameters and I want to connect it to a slot that takes a boolean always with the same value (e.g. a pressed() connected to a setEnabled(bool), where bool should always be True), I can't do that in Designer, it has to be in actual code - a trivial one-liner, sure, but still one more line of technical debt.
(INB4 "ur doing it wrong": yes, I know about clicked(bool), toggled(bool) etc, it was just an example to explain the concept.)
Thank you, but no. It doesn't fit the philosophy of the system I'd want to include it in.
Also, you get to use Tcl instead of Visual Basic, so even better !
Even Visual Basic 3's P-Code interpreter was faster than TCL string based one.
Thing is, if you want to speak about modern TCL implementations, then the comparison needs to be against VB.NET, with its 64 bit SIMD aware JIT/AOT compilers.
Here's a resource that may help: https://devguide.python.org/compiler/#introducing-new-byteco...
Part of my job used to be the large scale modification and recompilation of Android apps....you'd be amazed how many passwords are floating around in those.
Yes. There was a free third-party Java decompiler called JAD some year ago, for example.
> web application programming is gradually going to become the most important client-side programming out there. I think it will mostly obsolete all other client-side toolkits: GTK, Java Swing/SWT, Qt, and of course all the platform-specific ones like Cocoa and Win32/MFC
“The new API is HTML, and the new winners in the application development marketplace will be the people who can make HTML sing.”
https://github.com/kitech/qt.go
https://github.com/therecipe/qt
Both seem to be in active development. Does anybody have experience with either?
pipenv is dependency management on top of that
Qt had layouts years before html got the flexbox and gridbox too so I don't think there is a feature in html that is missing in Qt, Qt also includes QtWebkit if you ever need say to display some html or run some JS so basically you have access to native libraries and to JS/HTML if you need.
I'm genuinely curious: what doesn't Qt offer that a desktop app might need?
In Qt you use the Designer, you need to learn about the layout system if you want to do good UIs, but your GUI is saved in a file and then the c++/python code implements the event handlers and app logic.
The reason why developers, myself included, migrate to VSCode is really simple: because it's the best all-around cross-platform IDE right now for many scenarios, and because it has a thriving extension ecosystem to tailor it further. But it is that in spite of being written in Electron, not because of it. If Microsoft announced that it is being rewritten in Qt tomorrow, I'd be ecstatic.
Just to give you an example of what kinds of issues using web tech for desktop-like experience can cause:
https://github.com/Microsoft/vscode/issues/22900
(Yes, I'm well aware that they fixed it. The point is that the offending code needed to be written in the first place. A native desktop app using 13% of the CPU to render a blinking cursor would be considered an insane bug to have in the first place.)
Also, because QML is still not as good as the rest of Qt. But it's the right approach - a dedicated framework for desktop apps that is not built on things intended for completely different purposes (like HTML), but stealing the good ideas from there, like using a markup language to define the UI tree, and bindings.
Really, what we need is a cross-platform WPF with less fat. HTML is not it - it's cross-platform WPF with more fat, and not optimized for UI.