Guietta – Python module to create simple GUIs
github.com
github.com
Somehow, it feels like, CS education is getting both easier as new low friction tools are being made available each day and getting harder because the sheer complexity and number of things to know to really understand anything at all the levels of abstractions is getting more complicated.
- with higher complexity comes higher versatility. I liked how it enabled me to be creative - there are two well-written reference websites for learning it easily despite complexity (and that's important if you want your students to like/learn to read the docs) - the tkinter being shipped with Python meant quite a lot to me
However, the reason I did that many projects is that part of my class wasn't really into programming, so if you think that learning and using this will be significantly easier than tkinter basics, go with it, but I would recommend leaving tkinter at least as an option for "those who want to know more", i.e. students who are considering studying CS.
Whenever you encounter a new programming topic for the first time, it helps a lot if you encounter it in a fairly universal format.
I'm not sure about Python, but in most languages, there are simple GUI libraries that accomplish both of your goals: exciting students with interactive programs and helping them more deeply understand how GUIs are usually built and maintained.
Stuff like this is IMO the best way to learn programming for average people, because the first two blockers are usually:
* you don't understand what problem you are trying to solve
* it is all to abstract and you don't know what the thing you are doing actually is
Seeing what you do is a good way to deal with these points, because then programming can feel more like drawing a doodle instead of doing your taxes. Once they got the basics you could still dive into the rest.
IMO this would be the best way to start learning any programming language, because there is an simple IDE with examples, it is very visual and helps to convey basic programming structures just by doodling around.
If I (as a open source python dev) had to teach teenagers I would start with this
PySimpleGUI is indeed simple and quick, not very elegant but useful for small utilities.
Guietta starts with a Builder Factory method with List literal varargs (one List arg per grid row). Instead of .WidgetType() wrappers, Guietta infers widget type based on List element type and string formatting rules. The resulting column aligned code has the visual look and feel of a grid/table and makes it very readable. The choice of Qt-only seems reasonable.
There is probably a category of DSLs that try to mimic a grid/table layout rather than a natural language DSL (many Ruby style Internal DSLs). This is definitely the style I use for SQL DDL, using a strict grid-like layout for the column constraints and moving the verbose parts (like CHECK constraints) to the table constraints section at the end.
So, any pro'n'cons in comparison to PyQt?
All in all, it's a wrapper that hides complexity and flexibility from you. Might be what you need some times.
I am not looking forward to taking over projects using that framework abusing underscore and double underscore magic variables.
The underscore "_" is a pseudo reserved variable in python. It is used in assignments like year,month,_ = readdate() to discard the return value and disable the lint warning about it.
>>> from guietta import _ as underscore
to fix this?
from ssl import sslsocket
import httplib as hlib
You can think of the code above as remapping and/or duplicating the whole library it's importing. Python imports involve complex local and global states (I don't pretend to understand most of it).One direct effect on usage is that users of the library can call "httpclient.sslsocket" and "httpclient.hlib" as if they were provided by the library (the author certainly didn't mean to). This creates problem down the line when the author try to change the internal dependency, and this extends to other code also doing "import httpclient.sslsocket as sslsocket", creating problematic hidden dependencies.
More generally, this affects all import dependent features, like reload(module), mock, sys content, etc... imports are looked up and tracked by full path which doesn't always work as expected when paths are hot patched as above.
I used to work in a python shop (millions of line in total across the organization). Regularly had the problem with interns and new graduates abusing imports as above (sometimes even trying to change the existing imports because they though this was the better syntax). Then they couldn't pass their own tests (every new module must have a test) and asked for help after few hours of trying. Changing to a normal "import xxx" solved the problem. It's not always clear what was the exact issue, except side effects due to imports.
> users of the library can call "httpclient.sslsocket" and "httpclient.hlib" as if they were provided by the library
Well, they obviously shouldn't. And maybe they also shouldn't write Python code to begin with because, clearly, they're not able to adhere to Python conventions. Besides, why do you as the library developer care so much about what the users of the library do? If they don't follow your API specifications (proper API documentation should tell the users what they should and shouldn't do), it's their fault. I mean, people can and will shoot themselves in the foot all the time and in various ways. There's is nothing you can do about it.
> which doesn't always work as expected when paths are hot patched as above.
There is a reason why hot patching (and, by implication, mocking) needs to be done with care and only if you fully understand the consequences.
Regarding issues with mocking specifically, I suppose you're referring to nasty questions like https://stackoverflow.com/questions/14341689/how-to-mock-usi... ? Again, these things need to be done with care. (And of course the code also needs to be written in a testable way – no surprise here – and mocking should be done only if you've exhausted all other options.)
> It's not always clear what was the exact issue, except side effects due to imports.
Like you I am a Pythonista but I have honestly never run into any problems with selective imports (`from X import Y`) or import renaming (`import X as Y`) and much less even know what problems you're talking about. Overall, I find Python's way of importing modules rather straight-forward. (That is, as long as PYTHONPATH and __name__ are set correctly. From my POV, this is the only seriously annoying caveat.)
Anyway, I'm very open to changing my opinion but I'm afraid you'll have to be more specific about the issues you're encountering so often. (If you really did encounter them so often, I would think you would have noticed a pattern by now? No offense.)
Guietta looks interesting, but at a certain point if you're going to go with a visual representation of your gui to automatically generate it, you might as well go the whole docopt-style way and just have the whole gui defined in a docstring. That give you flexibility to have your own DSL as well (or jinja2 templates, or whatever), if you so decide, instead of needing to shoehorn python lists into the job. Plus that way you could actually modify the layout spacing, without much increase in complexity.
That being said, my usual recommendation for "I need a simple python GUI" is Toga [3]. The only downside is that Windows support is lagging behind MacOS and Linux, but it's not that far behind, so for simple stuff that should be reasonably acceptable.
[1] https://stackoverflow.com/questions/5893163/what-is-the-purp...
Same applies to C++ Builder, which MS still hasn't been able to match. C++/CX was the closest we got on VS, but then politics killed it.
In fairness, I haven't done any Windows desktop development for some time, so the XAML designer might be less crap nowadays.
Over the time this strategy proved beneficial. My team ended up having the highest salaries and bonuses in the company along with being given most interesting projects (developing new products from scratch as a rule).
I still went on my own after some time as I could not really tolerate that employer/employee style of interaction.
I'm curious how did you test candidates for this? Did you give them any specific tasks to accomplish and then evaluate their ability to learn?
Tools get popular for a reason. You get community support and a test-of-time guarantee that whatever you invest in today is more likely to last compared to the niche choice.
Sometimes/often for completely wrong reason. And even if the reason was good in particular context then suddenly the tool gets dragged to be used well beyond the original intent.
One example given is that if you're booking a flight for an executive "to New York" you should pick JFK, not because it's the best option, but because it's the most popular.
The reason is that if you pick Newark, say, and it all goes swimmingly, the best you can hope for is a "thanks!" .. whereas if there's a delay or some other problem, the person is likely to blame you for picking "a weird airport" (this story comes from a British perspective – I'm sure Newark is better known amongst Americans.. to reverse the story, it'd be like an American flying into Gatwick instead of Heathrow). If they got delayed at JFK, they're more likely to blame the airline, etc.
I'm thinking of digging into this a bit further as I think some of this explains why certain programming languages, tools, and services grow in popularity while others don't. AWS feels like the JFK of clouds, for instance. There's also the old "no-one gets fired for buying IBM" adage at play.
People pick AWS or JFK not because it's the best option but because it's guaranteed by popularity to not be the worst.
He's in lots of videos, TED talks, etc. if you want to get the cut of his jib for free, e.g. https://www.youtube.com/watch?v=iueVZJVEmEs
You seem to be mostly concerned with CYA here and in the JFK example.
>People pick AWS or JFK not because it's the best option but because it's guaranteed by popularity to not be the worst.
But this doesn't follow from CYA. It might be the best outcome for you, because your boss doesn't blame you. But it doesn't mean it's overall the best option.
I never had a great experience with IBM tools. They're the first example that comes to mind of software which gets bought because buyers aren't users in big corporations and buyers not having a personal incentive to choose better software.
In a large company with 100.000 employees where everybody loses 1h a week due to bad UX, slow UI and server restarts, you're losing multiple millions of dollars a week to protect your position.
If Newark is on average better than JFK, you're losing your executives time to protect your position.
I'm not saying protecting yourself isn't worthwhile, but it's a bad reason to pick tools from the company's perspective.
Absolutely, and that's the real point. I don't think I disagree with any of your points, but perhaps I am more resigned to the fact that people act how people act. I'm not super experienced in this area (which is why I was enjoying the book in question) but I believe this is all related to the phenomenon of "ambiguity aversion" (https://en.wikipedia.org/wiki/Ambiguity_aversion). I'm interested in how to engineer around (or cheat) these biases rather than present a purely logical argument for one technology (or airport!) over another.
I am lucky to work for myself and have non-technical clients so dont really have to worry about the latest and greatest just what works well for me :-)
Never quite a polished as Borland's offering of yesteryear (the GUI editor always felt clunky) but it's perfectly do-able.
PS: I really love Qt. It lets me do things no other framework can easily do. I love building performant, graphically heavy and fast user interfaces. It just wasn't built for mass-producing desktop forms that are connected to a DB.
There was just something so natural about the way you could quickly throw together a UI and then hook everything up to it.
* What's the tab order? (Usually whatever order they happened to be created in, which is often wrong after the UI has gone through some changes.)
* Are they really exactly the same size or only almost the same?
* How do they behave when the window is resized?
* Does one button have one of its many properties set slightly differently from the other one? (Have fun inspecting them all and make sure to not accidentally change anything while doing so.)
* Did you just accidentally move one of the buttons one pixel while inspecting things?
I prefer doing the UI in code, so that everything is clearly spelled out and not hidden in some properties panel. In WinForms it works pretty well with TableLayoutPanel.
Petzold wrote about this approach: http://charlespetzold.com/etc/DoesVisualStudioRotTheMind.htm...
Since then, I've seen .NET within Visual Studio almost get to the same quality we had with Delphi in 1995, but still way off.
Now that everything's a web app wrapped in something like Electron, it should be so much easier to have tooling like this, but yet we're all still building hugely complicated HTML rendering pipelines for something that was a solved problem a couple of decades ago.
Programming is manipulating cryptic colorful text. That sadly seems to be the definition we are stuck with. You start to get into anything that involves drag & drop, you are inviting other programmers to assume you are not good enough with cryptic text.
Its just a stupid psychological thing. And I think it holds back software engineering.
Analogously, the tools already available to computer users are tools that could harm the user if used improperly. To not empower users because they might harm themselves isn't progressive, it's paternalistic.
It's more that drag and drop isn't really good for much when it comes to programming. You can build GUIs with it and some extremely simple tasks like email joruneys, but for anything else visual programming has proven to be pretty poor.
Having used QtCreator to build a medium sized GUI, it was a pain. The XML it produces is too unwieldy to manually edit, so that's out (though I did edit it a few times to overcome bugs in QtCreator)
The QtCreator GUI itself is very robust but if you want to do something that's off the beaten path good luck, you're gonna be doing a lot of trial/error clicking and iteration. There were times when everything was "right" in QtCreator, and the result didn't work...
I would much prefer to use something like QtDeclarative if I do it again. It's easier to tell the computer exactly what I want, and then get exactly what I want, when the language for expressing what I want is concise and small.
Designer works great for GUIs with complex layouts. Having an intermediate XML representation puts a lot of distance between your code and your GUI. Sometimes this is good, other times is not. I rant a bit about this at the start of the introduction: https://guietta.readthedocs.io/en/latest/intro.html
radio buttons still basically unsupported - no way of grouping them.
Add optional astropy units for values, maybe extending the tuple syntax: ('__a__', u.km). More difficult than it seems, because one needs to parse input strings. But very useful in a scientific environment.
'with' syntax still very limited, in particular locals() and globals() refer to the Gui class scope so for example anything imported at the beginning of the script is not available inside the with block.
Unit tests almost completely missing, also I have no idea how to properly test GUI code.
Meta-level: add this list to github :)
One thing to add is a graph.
or were you thinking of something else?
There'a a gap a mile wide between
1) tools like Delphi, VisualBasic (the classic version, not .net), and to some extent, HyperCard
2) GUI builders, which were popularized by Visual C++
#1 doesn't have (visible) layers or abstractions. It's a different way to represent your program. You place a few controls, tie them to actions (code), and that's your system.
#2 is like onions, with lots of messy layers, and tend to be way more cumbersome to deal with than the code itself.
I don't know of modern-day graphical programming systems. I haven't kept up with Delphi, but people who have claim the last useful version is Version 7 from 2002. After that, it went through some messy transition.
That's the only thing I know that's really seamless like old times.
* Don't have to change the program to change the UI
* Don't have to change the UI to change the program behaviour
* Easy to include in version control
It was almost akin to HTML and progressive JS.
I wish there was a GUI toolkit where you would specify what kind of interaction you need, and it builds the right GUI elements with the right workflow following best practices by itself. Sort of like what Ruby/ActiveRecord does for databases.
It kind of popped up out of nowhere, fully-formed, or at least I became aware of it when it was pretty mature. It's basically Visual Basic for Python, and worked really well. I have no idea why it wasn't more popular.
I have always preferred to code my UIs though, rather than use a GUI designer. I just find the back-and-forth between graphical designer and code an annoying extra context switch every time. Also in code I can position elements exactly, or use sizers very fluidly where GUI designers are fiddly and imprecise. They can be useful to do an initial mockup, but not much more so than pencil and paper. YMMV, we all have different visual and mental cognitive models for these things.
"A little"... it's straight outta the '90s. I am as nostalgic as anyone but even I don't particularly long for that æsthetic.
I think Tk widgets are themable.
It doesn't have to, it supports theming and there are even themes that use the native GUI.
e.g. https://wiki.tcl-lang.org/page/List+of+ttk+Themes (search for “native”)
Kind of like a phonebook starting with companies like AAAGarden, now you want your module name to be short to get to the top ;)
Edit: Found some discussion on this topic: https://stackoverflow.com/questions/20762662/whats-the-corre...
Especially the alphabetic ordering is important in my view. Makes parsing/reading and spotting duplicates much easier. It is also PEP8 style [0].
For all these reasons, I think the pyramid style is awful in comparison.
Since Python imports can have side effects, the order can matter. But to the extent that it doesn't break anything, alphabetically sorted groups seems deterministic and readable.
I think this might be the most popular implementation for auto-sorting: https://pypi.org/project/isort/
[1] https://www.effbot.org/zone/element-tkinter.htm
[2] https://github.com/calroc/pygoo
[3] http://pages.cpsc.ucalgary.ca/~aycock/spark/ "Scanning, Parsing, and Rewriting Kit"
In the example, there is the button called 'Calculate' and then action define in "gui.Calculate" block. But what if the name of the button was 'Calculate it'(with the space between words)? The action header would be gui.'Calculate it'?
It is also possible to set a custom name using a tuple syntax (widget, 'name'). Like this: (['Calculate'], 'myname')
Then your central state is assigned to a Subject and all widgets have an reference to an observer. As soon as the central state value changes, the callback in the observer is triggered and you can fire the update method for the widget using the central state value.
Apart from that, this seems to be a wrapper on top of PySide/QT to speed up development of basic forms. I don't find it particularly attractive, I have a feeling one will have to drop into QT as soon as requirements get slightly complex. Then again, if it gets more people to approach QT and desktop GUIs in general, it's welcome.
It made me chuckle a bit :)
>GNU Library or Lesser General Public License (LGPL), Other/Proprietary License (LGPL)
So, is it okay for Guietta to be MIT?
I'm still confused though. If I create an application using Guietta, do I have to follow MIT or LGPL3 terms?
But will quickly devolve into a morass if you need to do anything beyond a simple grid.
Thought I'd mention that as it might be something useful to others.
In the README, Quit is a button but doesn't appear to be consistent with the syntax of other buttons like ['Calculate']. Is there a reason for this?
Also, how do you bind buttons to functions?
Binding is done using QT's signals/slots mechanism under the hood, and can be done in several ways:
- using the 'with' statement as in the example, but this is often limited
- using an events layer, that is, a replica of the GUI layout, with a callable for each widget that you want to bind.
- using the @gui.auto decorator on a function: it will try to guess.
All this is described in the tutorial: https://guietta.readthedocs.io/en/latest/tutorial.html , chapter "GUI actions"
edit: tried:
"UnboundLocalError: local variable 'loader' referenced before assignment Fatal Python error: could not initialize part 2
...
'python script.py' terminated by signal SIGABRT (Abort)"
:(
PyQt is not really difficult, just boring. And a bit of magic was indeed the intended effect :)
And regarding the "same old shit", you'll be entitled to spit on mature frameworks when your GUI from scratch supports screen readers, 3D acceleration and printing with the same API on Windows, Linux and OSX.