Hello Qt for Python
blog.qt.io
blog.qt.io
[1]: https://fman.io
Also, what's PySide/PySide2?
In particular: https://github.com/DaveMDS/egitu
https://phab.enlightenment.org/w/projects/python_bindings_fo...
Scroll down to "python projects using EFL".
EFL has a number of questionable design choices, covered a little bit here: https://what.thedailywtf.com/topic/15001/enlightened .
[Py]Qt of course is cross-platform with the local look/feel.
PyQt5 and Qt for Python is a 1-to-1 binding to the original Qt and their APIs are almost identical, so you should be able to switch to Qt for Python quite easily when it is stable.
By the way, Qt for Python is re-branded from PySide2. They are the same.
I don't know much detail about PyQt5 vs PySide 2 but at least the overall logic should be the same.
[1]: https://github.com/epage/PythonUtils/blob/master/util/qt_com...
Since then, bugs have been smashed, modules have been added and improvements have been made. I would recommend almost anyone to start developing with this right away and, like always, report bugs [0] and contribute improvements back to the project [1] (not on github).
In fact, when I tried variations of Qt for py, I just quit out of frustration with how things either didn’t work or didn’t work very fast, now I just stick with Tkinter.
To be honest most of the QT solutions for Python are pretty fidgety . The recent wxPython releases (4.x) work out of the box direct from PyPI, not too much to worry about licensing.
For Qt, it's... the licensing is usually just fine for people but it's complex enough to where things like maintaining your own fork (pretty easy in Python compared to C++) is not super easy. But there's decent Python support, so it's more "do you want to use Qt or wx". Both systems have good enough support.
It's most definitely not the most complicated thing, but when your processes are based off of BSD'd libraries, you gotta think a bit harder about Qt usage, if only for it falling outside the normal scope of things.
Perhaps PySide's return will encourage some competition in the Qt space for Python. For example, I wish it was simple to create a cross-platform installer for stand-alone Python apps that use Qt. Current solutions suffer from the 80/20 rule where the 20 usually contains something essential.
In order to use this, if I read the tutorial[1] code correctly, I must modify my app to wrap everything -- or at any rate, all PyQt-related things? -- inside an AppContext, and modify the outermost level to create this.
If so, this is easy enough for the tutorial but what if my app opens multiple windows and has code to create them spread over multiple modules (as one of mine does). Is there a simple way to get all these bits into one "context"? Or have I read too hastily?
Yes you should use the AppContext. You don't have to convert your entire app to it. Only enough to "start" your app. (I highly recommend the app context approach where possible however, it's just so clear.)
It will setup exactly what was asked for. Specifically qt 5.9.5 with PyQt.
>> How well does that work on OSX?
> conda install pyqt
Your comment, while presenting a potential solution to the original problem, did not make sense in context and went off in another direction entirely.
> I’ve tried many times over many years, but never got a satisfactory working Python + Qt development environment working on the Mac.
Edit: I should say, there are MacOS-unique difficulties if you want to bundle your nice PyQt5 script into a standalone MacOS app bundle using PyInstaller. But that's a separate issue.
But all of these things have improved greatly, in my recent experience.
On Linux you might want to get the distros qt/qt-dev packages, as usual. But as far as I can recall, you generally don't have to.
I've maintained a production PyQt based app for 7-8 years (started on PyQt4/py2, moved to PyQt5/py3, but I evaluated PySide as well). It involved wrapping another Qt library for use from python. I found the bindings I created based on SIP (which is what PyQt is based on, both written by the same author) to be overall easier to create and smaller in size.
It's great that we're getting Qt backed bindings but Phil Thompson has done a wonderful job with PyQt over the years and I really would've liked to see it become the official library somehow.
I know that those are things you have to worry about when you write C++, but when in the python world, you kind of expect everything to be refcounted for you. If I ever have to write a GUI app in python again, I'll probably chose another framework.
The owners of PyQt (Riverbank) depend on that product to survive; whereas Qt has bigger fish to fry most of the time. The incentives are very different.
Digia later spun off The Qt Company, which develops Qt and is now developing PySide2, so this is actually the first time the same organisation has developed both Qt and Python bindings for it.
For many purposes (including mine), PyQt is very expensive, so I'm really hoping PySide2 goes somewhere.
"PySide2 – the bindings from Python to Qt – changes skin this spring. We have re-branded it as Qt for Python on a solution level, as we wanted the name to reflect the use of Qt in Python applications. Under the hood it is still PySide2 – just better."
Qt (Qt Desktop) bindings for python are welcome. But, it's not a suitable for a viable replacement for electron. Maybe Qt Quick, but even qt quick has some decisions that can make incredibly uncomfortable to use in large applications.
Just like its predecessors I give it one or two years more max, then it will fade away like they did.
In fact, Python is at a disadvantage here anyways because it's not async by default.
Threads avoid the need of callbacks/promises/async/await and they're also cheap and performant unless you need to spawn >10k of them, which seems very unlikely in a desktop applications.
Being async by default is an advantage when you need to handle hundreds of thousands of tasks, all of which are mostly waiting on I/O, which is something that can happen on server side applications, and almost never on the desktop.
I find that really strange. The same holds for most other GUI libraries, like WxPython.
It seems the only real pythonic GUI libraries are Tkinter and PyGobject.
Those are things that make it better for the library maintainers, sure, but presenting (and documenting) an API that is idiomatic, both in structure and behavior, for the host language is better for library consumers, as it doesn't force them to context switch between the idioms of the host language and the idioms of the foreign library.
There are already examples in the "Hello Qt" which are easily solvable:
app = QApplication([])
# should read instead:
app = QApplication()
where the empty list is the default argument. Also app.exec_()
# should be instead
app.exec()
as it is also in the C++ API.These small things make the difference.
I agree on your first example.
I find PyQt to be Pythonic in all the ways that count, e.g. replacing `self.setFoo(bar)` with `self.foo = bar`, decorators for signals/slots, etc.
import logging
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger.addHandler(...)Generating similar high quality docs for the Pythonic wrapper should not be a issue.
Isn't the point that you don't have to translate in your head all the time. For non-Pythonic, non pep8 code you are going to do that constantly, not only when you read the Qt docs.
pep8 is a subset of 'Pythonic', the current wrappers are not only not pep8 compliant, they are also un-Pythonic in other ways.
Don't get me wrong, I appreciate Qt trying to expand their user base, but I would consider this effort a early milestone on the road to something that really fits into the Python ecosystem.
... uh ? the designer is part of the ide... nowadays you even have a code view synced with the UI editor in realtime (http://blog.qt.io/blog/2017/05/24/qt-quick-designer-qt-creat...)
[0] https://github.com/ssebastianj/ia2013-tpi-rl/blob/master/gui...
Going back and forth between Qt Designer and PyDev was (is?) ancient. Unfortunately I couldn't find a way to automate the compilation step (perhaps with a hook from Qt Designer?)
There's also Avalonia, but it's currently in beta:
Here is one post and a thread with many pros and con views about Delphi:
Delphi – why won't it die? (2013) (stevepeacocke.blogspot.com)
The general design is this: there's a code unit (.pas) and declarative UI property file (.dfm) for every form in your application. When you modify any published properties for any controls/components on the form via the object inspector, these modifications are stored in the .dfm file. Any changes to the controls/components on the form (adding a control, removing a control, renaming a control) are immediately reflected in the .pas code for the form. And, the code is not just generated code that you can't touch, it is code that you are modifying along with the IDE. You can jump back and forth between the UI designer and code editor with a simple F12 key press.
When an application is compiled, the compiler automatically bundles the .dfm files as resources in the resultant binary and streams the properties in during form instantiation.
Where this all really shines is with event handling. You can, for example, double-click a button on the form and the designer will drop you into the code editor with a fully-defined OnClick event handler all ready to go. This is because Delphi has the concept of default events for controls/components. For non-default events, you can do the same by double-clicking on the event name in the object inspector.
The other thing is that the UI designer is running real code in the background for controls/components, so the design-time environment mirrors the run-time environment, and control/component designers can interrogate the RTL to find out which state they are in, and act accordingly. You can also write custom property editors that allow for complex property editing in a nice interface.
Our product, Elevate Web Builder, works exactly like this for building single-page web applications. It's extremely productive and a very good fit for web applications because, unlike desktop applications, there's not as much risk of mixing back-end code into your UI code and starting to makes things messy.
The key is that you need a strongly-typed language to make this all happen, so I'm not sure how applicable any of this is to Python.
That said, especially the custom property editors would make e.g. Xcode’s interface builder almost worth looking at. I’ve just given up on graphical designers at all—last I checked thy were all terrible with responsive design, which is ironic on an ide that claims to target a mobile platform.
As for responsive design in graphical editors: what part do you find that they are terrible at, or is it that they don't do it at all ? Our previously-mentioned Elevate Web Builder will allow the developer to design responsive layouts that flow and move as you resize the container in the designer so that you can see how the design will behave at run-time.
1. SIP files are generated and dropped into the tarball: no way to do that yourself (the tool is available, but completely undocumented). This is problematic when a new major Qt version is out, but PyQt hasn't updated yet (I had problems like this recently when building PyQt5 for Qt 5.11 for openSUSE)
2. There is absolutely no bug reporting: you have to join the mailing list, post about your issue, and hopefully get an answer or "fixed in next snapshot" (see below)
3. There's no source repository access, just frequently-released "snapshots". Backporting patches to stable releases (because perhaps fixes aren't in old versions) is a chore.
4. Submitting patches as well requires a ML post: not bad per se, but there's no real workflow for it (and hard to do anyway without having the current state of the code).
I don't have to use PyQt professionally (all my stuff is parsing/querying/stats, so a GUI isn't necessary), but for my free time projects I preferred to learn C++ and Qt than go through PyQt again. And it's a shame since the bindings are quite good in quality.
Later, Qt became GPL + LGPL + commercial. However, PyQt, didn't want to add LGPL and stayed dual licensed. Qt thought "ok then, will have to do it by myself" and created an alternative to PyQt called PySide, which was GPL + LGPL + commercial.
That was in Qt4 time. Then Qt5 came, and PyQt5 appeared, while PySide was still in Qt4 land.
Then PySide2 happened, now known as Qt for Python.
> Initial research into Python bindings for Qt involved speaking with Riverbank Computing, the makers of PyQt. We had several discussions with them to see if it was possible to use PyQt to achieve our goals. Unfortunately, a common agreement could not be found , so in the end we decided to proceed with PySide.
But the project owners (Riverbank) support PyQt just fine, and arguably much better than Qt ever supported PySide in any previous incarnation.
pip install --index-url=http://download.qt.io/snapshots/ci/pyside/5.9/latest/ pyside2 --trusted-host download.qt.io
(with python 3.6 or 2.5)I'm also working on a similar solution for .NET Core: https://github.com/pauldotknopf/net-core-qml
Almost no documentation was avaible and I was learning how GUI works. It took me a while to get a basic app running and from there I mostly translated the official docs to python.
If I were ever to write a desktop app, which one should I choose, given I'm equally comfortable with both languages?
About your second question (c++ vs python), even I am curious
Put in plain English it is like this. I write quite a lot of code that integrates various enterprise systems together. Things like EDI management, and 'brokers' between incompatible API's. It is usually a mixture of Python/Bash/SQL. It is not my full-time job to code, but I get things done. As complexity increased I learned about version-control, OOP, and unit-testing. I have some pretty complex stuff in production. So I can self-learn all of those things, but not Python GUI programming
The kind of thing I would happily launch from the command line, often needs a GUI when end users are involved. Even to have an app that takes an input>click OK>do some API stuff>return an answer seems absurdly complicated in Python and [insert whichever GUI framework]. In fact I find it simpler to add a web front end and a server than I do a desktop GUI. Qt was never on my list as I have enough battles to handle without negotiation with bosses for PyQt licensing costs. Hence my interest in this development.
I didn't have this trouble with VB6 or VB.NET. Draw a box>draw a button>double-click the button>add the code you want to run when the button is clicked.
When I do the same in Python I have dozens of lines of set-up code. I have a window with a text box and a button, surely that should be three lines of code (like in html)? Then I find that things are not running in the order I expected... Imagine for instance I want to put an alert box up that says "working", then call the function to do the work, then take the alert box away when the function exits...My Python head says this should look like this
def on_ok_clicked(event):
alert=framework.alertbox(text="working...")
do_important_blocking_stuff()
alert.destroy()
and instead I find the GUI hanging while the function is running, then the alert box flash up and exit, or something equally unintuitive.There doesn't seem to be a Pythonic or indeed simple way to handle these super straight-forward use cases. I have no aspiration to be a UX person, or learn a new paradigm just to have a button that says "GO!". I'm guessing from the other comments that Qt for Python is not going to be my savior.
No, that's not "your python head", sorry, that's your "VB head" at best. That's lack of knowledge of how desktop GUI paradigms actually work and what an event loop is and how it interacts with threads.
I do not disagree that VB (and Delphi) did a better job at hiding these concepts from the "just getting it done" crowd, but don't blame it on Python if you don't have a grasp of how C++ GUI toolkits actually work.
I'm not blaming it on Python, honestly. I'm just really surprised that there isn't a framework that will hide that stuff from me like VB did. You are a 100% correct in that I don't know anything about desktop GUI paradigms, or C++ GUI toolkits. I really don't have the bandwidth to find out either! I'm also surprised that I need to. I don't think that is even my VB head, I am a business systems person who has successful modeled a physical process in software. In a recent case I did all of the work negotiating with vendors/management/users, I found the bugs in the vendors API, and I did this to an absurd deadline (with almost zero budget) created by a a vendor withdrawing a product with no notice. That's the kind of absurd thing us plebs in the "just getting it done" crowd have to do all of the time. But I am finding that simple GUI launchers for my software are really complicated in Python with the frameworks I have found. I am shocked that this is the piece that is defeating me! As I said before, I could write a web front-end for this kind of thing relatively easily (in the above case it was a hardware requirement that lead me to try again at the desktop GUI). Perhaps this is why we see so many people looking at the web-app-on-the-desktop that is so derided on these pages?
Although I've heard good things about Lazarus IDE, probably your best bet for such projects. Pascal is not hard to learn, or re-learn.
I don't really like working in an IDE, or need to. I am happy to design GUI components in a markup language, for the kind of use cases I am talking about.
However would it not be possible to hide the complexities of managing a GUI in the framework/bindings so that the Python user just has to deal with "Someone clicked OK>Run this function" in as easy a way as VB did?
I mean I don't know much about how to send a http request in C++, but I can do it in 'requests' without much problem!
Thanks for the advice on Lazarus. Not FOSS and not desktop, but I have been looking at Anvil recently, which makes it really easy to code web app front ends, allowing me to concentrate on backend stuff.
If you don't want one, QML is what you are looking for.
Saw anvil and it looked interesting, aren't apps tied to its system however?
However I still find similar issues with Tkinter as I discussed above, I really didn't expect to have to learn how Tk event loops or whatever worked just to get my code to execute in the order it is written in! I guess I was just naive.
The blocking thing you can do in two ways. First, put your blocking stuff in another thread and do it there, and when it's done call back into the main thread to tear down the alert.
The other way, to play nice with the event loop, is to do something like:
makemydialog()
Tk.update_idletasks() # process events so that the dialog shows up
do_my_stuff
teardown
If within do_my_stuff you can periodically call update() to process events, it'll give the appearance of being more responsive.After you get a bit more experience with doing some GUI stuff, and if you want to have a more long-running GUI, it will become more natural to think of initiating everything in response to event handlers, as opposed to the batch model of running your program linearly from top to bottom.
I guess looking at it, having a process that is going to take a few seconds and must block the user from progressing until it completes is perhaps not the scenario most tutorials envisage. Thanks again
In other frameworks I just say "this frame (containing lots of widgets) is scrollable" by setting one property to true and it just works. Including vertical and horizontal scrolling, mouse-wheel support, and standard keyboard shortcuts like page-down etc.
In Tkinter this seems almost impossible. It takes dozens of lines of code; many events must be implemented manually, including low-level things like calculation of scroll offsets; good mouse-wheel support is very difficult; etc. It feels more like I'm _implementing_ (rather than _using_) the scrolling widget. And in the end it the UI flickers like crazy during scrolling.
Is there something I overlooked?
For instance, https://github.com/billsix/pyNuklear/blob/master/demo/overvi... (this function is called repeatedly on each frame) is not significantly different from the example at https://reactjs.org/tutorial/tutorial.html#what-is-react ... but it is very different from something like `div = createDiv(); div2 = createDiv(parent=div)` etc. which would be a retained-mode API.
Qt also offers QML, if you are a fan of how those components look you may enjoy using it.
Also, the API does not seem Pythonic at all.
Meanwhile, PyQt just chugged along just fine. Riverbank must keep focusing on it all the time or it will die. The incentives are very different.
PySide is waaaay more Pythonic than PyQt ever was. Types are actually translated to Python native types and APIs are way more Pythonic and not just translated 1:1 like PyQt.