17 votes

Tkinter vs PyQt vs wxPython vs PyGtk vs Kivy: Too many options with nuanced pros and cons causes analysis paralysis and difficulty in taking decisions

The good things about Python which make it a very ubiquitous language worthy of learning (platform agnostic, elegant syntax, portable standard library and ecosystem packages, etc.) unfortunately also has this weird side-effect of causing tremendous pain when it comes to choosing which library or toolkit to use for say, a side project for a Desktop GUI app.

It seems as if researching about these Python GUI toolkits, finding out their pros and cons and nuances has itself become a dedicated project of its own and I have almost forgotten about the actual app and user story for which I was looking them up in the first place!

Though I'm almost certain at this point that Kivy isn't something I'm going to use. I don't want my app to run on android, at least not presently. And even if a need arises in future, a more efficient path there is to use something like Java with an Android IDE.

Plus a 100% pure python toolkit means some sacrifice in performance. With PyQt and PyGtk, you can get the raw performance of underlying C++ and C runtimes respectively which they wrap.

Now tkinter and PyQt is where I'm really confused and not able to decide which one to use. The pros of tkinter are highly appealing to me, to be honest. The fact that it comes built-in with python and right out of the box - which incidentally also frees you of all the licensing hassles unlike PyQt/PySide stack is also a great plus. Though this particular project is going to be open source anyway, so it shouldn't matter much. But in the long run and generally speaking, it's clear that one has the licensing advantage here.

Secondly, tkinter also has the advantage of being smaller in size. Since it comes built-in, the final portable EXE size would perhaps be as small as that of just the portable python interpreter using PyInstaller or something?

But on the other hand, smaller size doesn't really matter in the age of gigabyte high-speed Internet, does it? And I've seen some PyQt projects too that seem to create smaller bundles with efficient packaging, wonder how they are able to do that!

One criticism of tkinter I came across is that while getting started with a Hello World GUI is easy, making something non-trivial soon leads you down a rabbit hole which is filled with messy and hacky workarounds. For example, there isn't a native or built-in support for creating a system tray icon for your app which is considered pretty much a standard feature for desktop GUI apps these days. Even for adding this trivial feature to your app, you must install a third party package called pystray which isn't a very thrilling experience at all. Imagine what all you'll be going through if you want to implement say a complex data grid with dropdown widgets or a complex tree view widget.

But PyQt, on the other hand, also has its own set of criticisms. For starters, since the core toolkit is written in C++, the Pythonista must hack their way through all the object orientedness mandated by the core libraries in ways that don't seem very pythonic. For example, you can't pass a simple tuple with (x,y) co-ordinates for a widget location or size, you must find the corresponding widget class such as QtSize or whatever to be able to do that.

This is what I got from my reading and youtubing so far. I don't know how hard this usually is in practice. Coming from a C# and Java background, I don't think it should be for me. But I'd like to know from more experienced Python programmers who have traversed both these paths (tkinter and PyQt) - which path is better as a learning investment in the long run?

14 comments

  1. [2]
    arqalite
    (edited )
    Link
    Personally for my use-cases (simple but nice-looking GUIs for corporate internal software), Tkinter with ttkbootstrap is my go-to. It's fairly light and easy to set up, and the default themes are...

    Personally for my use-cases (simple but nice-looking GUIs for corporate internal software), Tkinter with ttkbootstrap is my go-to. It's fairly light and easy to set up, and the default themes are nice, so I can get something that looks decent and works nice pretty quickly. Also fully cross-platform.

    If you want some eye-candy (integration with W10/W11 Fluent UI, for example), it's not as good but I would bother with creating stunning UIs only for commercial, publicly-released apps, which I don't do much lately, so I can't speak about it anyway.

    EDIT: Just saw the section about Tkinter being very hacky once you want to do something it doesn't fully support - yeah, that happens a lot, and I think I got used to it, but it's a very valid criticism.
    It's hard to write cross-platform software and also integrate with OS functions like system trays or docks.

    I don't have any advice regarding that, but I would ask if you really need cross-platform support. As a Linux (and arm64) user I hate when apps aren't compatible, but I also understand that most of the time as a developer you should focus on your main goals, and if you mostly use Windows, it's completely alright to focus on it only and develop using Win32 APIs for example. I believe it's more important to get your app working on the system you use and arr most comfortable with, than spend valuable time picking a GUI package that works on other systems. But that also depends on what the app is, and what is the target audience.

    Also, focus on the features you actually need. It's nice to have the option of creating a system tray, but unless you actually have a need for one, it's not worth focusing on that capability when evaluating GUI toolkits. One of my core lessons as a software developer was "if you ain't gonna need it, don't build it", and focusing on user outcomes and delivering what they need.

    Since it's a side-project, I assume you aren't bound by any deadlines or timelines, so why not experiment at first? If I found myself overwhelmed by choices, I'd go with my gut, or the choice I'm most naturally drawn to, and start building with it. If it later hit a roadblock, I'd scrap that codebase and start again with the next option that doesn't have that roadblock. Nobody likes scrapping their work, but I also find value in the experience of writing code, trying new tools and just having fun with tech, so for me it doesn't hurt as much (in fact I recently started a project in Python, then restarted it as a TDD project but still in Python, then moved to Rust because I needed the speed boost). At the end, you'll still learn something new.

    Probably none of this will be useful to you, but I wanted to write it anyway. Good luck with your app, by the way, and share it with us when it's released!

    8 votes
    1. first-must-burn
      Link Parent
      This is great advice. My experience is that if its going to become remotely real (lots of users and platforms), you're likely to do major overhauls anyway because you're going to have learned a...

      Since it's a side-project, I assume you aren't bound by any deadlines or timelines, so why not experiment at first?
      If it later hit a roadblock, I'd scrap that codebase and start again with the next option that doesn't have that roadblock.

      This is great advice. My experience is that if its going to become remotely real (lots of users and platforms), you're likely to do major overhauls anyway because you're going to have learned a lot about the real requirements from your user base. If it never gets to that stage, then whatever you picked initially is probably fine.

      3 votes
  2. Happy_Shredder
    Link
    I just use PyQt. It's super easy with all the widgets I need, and the performance is acceptable. Great documentation too. (i did originally learn the c++ qt api which may bias me)

    I just use PyQt. It's super easy with all the widgets I need, and the performance is acceptable. Great documentation too.

    (i did originally learn the c++ qt api which may bias me)

    4 votes
  3. vord
    Link
    I wrote an app with Tkinter awhile back. I later rewrote it in PyQt, and it was better for it. Tkinter was faster to onboard, having never made a GUI app, but I ran into walls with what I was...

    I wrote an app with Tkinter awhile back. I later rewrote it in PyQt, and it was better for it.

    Tkinter was faster to onboard, having never made a GUI app, but I ran into walls with what I was doing fairly quick, and Qt didn't require me to reroll as much basic OS integration to get things done.

    Both were loaded with their own idiosynchracies, but PyQt had better documentation.

    3 votes
  4. [2]
    PuddleOfKittens
    Link
    PyQt has QtWidgets and QtQuick, which aren't exactly the same thing. QtQuick lets you create declarative interfaces using QML, which was The Future when it was introduced in ~2009 with QtWidgets...

    PyQt has QtWidgets and QtQuick, which aren't exactly the same thing. QtQuick lets you create declarative interfaces using QML, which was The Future when it was introduced in ~2009 with QtWidgets being deprecated, but that was sort of abandoned when it turns out the paying companies with legacy stacks from the 90s aren't remotely willing to deprecate their code.

    I've only used QtQuick, but for documentation at least QtWidgets has to be treated like a whole separate GUI toolkit; it makes searching for documentation a pain in the ass because "PyQt" can sometimes return irrelevant Widgets stuff, and isn't guaranteed to return all relevant stuff because sometimes it'll be under "pyside" instead.

    Also, QtQuick is bugged and doesn't properly support tablet events (read: stylus tilt/pressure, they're called "tablet events" because Wacoms are older than iPads), but at least it does support them, whereas other toolkits tend to treat 'tablet events' as an afterthought.

    Speaking of which, tablet events are waaay more complicated than they sound. It's not just an X/Y coord with press/change/release events like mice, it also needs to pass tilt/pressure/rotation (all three are analog valuees, tilt being how parallel/tangential to the tablet the stylus is, pressure being pressure, and rotation being treating the stylus like a spinning-top), tilt/pressure/rotation change events, 'hover' events (this is where the stylus is a few mm above the tablet but not actually pressed down, some systems can detect how far the stylus is from the screen so it's analog), a constraint that hover events can't be triggered while the stylus is pressed (ez), stylus buttons (which are physical buttons on the side of the stylus used like keyboard shortcuts, and I think at this point the SDL people are talking about just talking about reserving six degrees of freedom?

    Except people tend to expect styluses to work as mice, so you need to send both a tablet and mouse event with one of them cancelling the other (so that people can quickly use the stylus to click buttons in photoshop), and it's not clear to me which should take priority (I think it might depend on the usage context - for buttons its mouse, for drawing areas it's tablet), and hover change-events should be translated to mouse-move events but tilt/rotate/pressure events shouldn't. The important thing is that if you send them both unconditionally and the application code doesn't handle it itself, then every press will be a double-press without a release inbetween which mucks a bunch of code up.

    Also, different styluses have different features - some have pressure but no tilt, some have tilt but no hover, you'd want to just send them as zero but that could cause complications because the real answer is you don't know, so you'd want to communicate with the application what features are even enabled.

    Anyway, I understand why most toolkits don't properly handle tablet events. Basically nobody uses the things outside Krita, which is written in QtWidgets.

    2 votes
    1. pyeri
      Link Parent
      Thanks. In this particular project, I'm not going to need any tablet events support, it's entirely a desktop app but I don need proper cross-platform support (Linux/Windows/Mac) which is sometimes...

      Thanks. In this particular project, I'm not going to need any tablet events support, it's entirely a desktop app but I don need proper cross-platform support (Linux/Windows/Mac) which is sometimes difficult to get even with high level toolkits and languages.

      I'm leaning more and more towards tkinter for this one. At least the two solid advantages it has (built-in or smaller bundle size, no licensing worries) probably more than compensates for what it lacks in comparison to PyQt (fewer widgets in comparison, less elegant API, etc).

      1 vote
  5. JoshuaJ
    Link
    Personally we have used python as a backend and then packaged the front end as a web based electron app. Decoupling the UI from the App and serving it as an API let us think through things a...

    Personally we have used python as a backend and then packaged the front end as a web based electron app.

    Decoupling the UI from the App and serving it as an API let us think through things a better way. It also meant that when the day came for deployment, instead of sharing executable files, we dropped electron and could just host everything online.

    2 votes
  6. [5]
    Tynted
    Link
    Hey there, this thread made me wonder about this. I'm thinking about putting significant time into learning coding in 2024 and I wanted to ask at what point this kind of thing affects a developer?...

    Hey there, this thread made me wonder about this. I'm thinking about putting significant time into learning coding in 2024 and I wanted to ask at what point this kind of thing affects a developer? These kinds of things worry me a little bit about preventing my enjoyment/learning of programming. Treat me like I'm a complete beginner. If I'm interested in Python, should I just stick with that for a long time until I know enough to realize that these other flavors (correct analogy?) you all are talking about will be helpful to me?

    2 votes
    1. [3]
      Bwerf
      Link Parent
      This thread is about building GUIs in python, and different libraries for doing that. If you're interested in having buttons and text fields and images in a window that you created with python...

      This thread is about building GUIs in python, and different libraries for doing that. If you're interested in having buttons and text fields and images in a window that you created with python this will be relevant for you. This is not about alternatives to python, but comparing different extensions to python.

      4 votes
      1. [2]
        Tynted
        Link Parent
        Oh I see! I kinda read through this quickly and obviously didn't comprehend it very well 😅

        Oh I see! I kinda read through this quickly and obviously didn't comprehend it very well 😅

        2 votes
        1. Bwerf
          Link Parent
          No worries, it can be hard to grasp the meaning of things when you're in a new field. =)

          No worries, it can be hard to grasp the meaning of things when you're in a new field. =)

          2 votes
    2. pyeri
      (edited )
      Link Parent
      These kinds of things will start affecting you once you've learned the basics of a programming language (constructs, variables, standard functions, package ecosystem, etc.) and then want to...

      These kinds of things will start affecting you once you've learned the basics of a programming language (constructs, variables, standard functions, package ecosystem, etc.) and then want to implement something as a first real world project, or even a side project at a later stage in career.

      The package ecosystem is really large and ever growing, especially for popular languages like python, java and node. You want to make sure that you use the best tool or package for your particular project which isn't always going to be easy. But coming to think of it, this isn't related to just programming, it's just a reflection of the fact that too many competing "less than perfect" options will cause you to have this dilemma. You'll want to stop and examine each one in some detail before proceeding as each path will take you on a very different kind of journey and you want to know the terrain well beforehand.

      Consider the early days of your 12th or pre-college grade years when you chose computer science as major over all other competing options like physics, maths, astronomy, medicine, etc. You must have at least given some thought on how you'd have fared in those other areas, right? You studied all the pros and cons, then concluded after weighing in all the factors that CS is for you.

      But once you actually make that selection, then it becomes your karma! You then have to stick with all the good and bad aspects of it. Thankfully tkinter vs pyside isn't that kind of irreversible decision and eventually one can easily find themselves working in both, but as far as analogies go, this one seems to be apt and conveys the point.

      1 vote
  7. Reapy
    Link
    Just to throw on the pile I did a first python based gui and used dearpygui for it. Initially I really liked it, it was very fast to have something up on screen and working, there are a ton of...

    Just to throw on the pile I did a first python based gui and used dearpygui for it. Initially I really liked it, it was very fast to have something up on screen and working, there are a ton of widgets for it, documentation was reasonable ect. However one critical thing was missing, I could not for the life of me find a layout manager or layout code at all for it.

    If you left align everything it is fine, but to center I could only think to make a table with 3 cols and put the stuff in the middle. It ended up driving me crazy and if I have to write another gui in python I'd try something else.

    I also 100 percent want to find an excuse to use textual, it's basically a gui library thst runs off the console and looks amazing. I had used the authors 'rich' library before which is great for formatted output. Just the idea of gui via console is so cool to me though.

    2 votes
  8. Woeps
    Link
    I just started with creating some Python GUI apps and with all the options out there I just decided for Kivy/KivyMD ... The analysis paralysis is something I'm very familiar with so I just...

    I just started with creating some Python GUI apps and with all the options out there I just decided for Kivy/KivyMD ...

    The analysis paralysis is something I'm very familiar with so I just randomly picked this one.
    I'm definitely no expert (I'm more of an OPS/CICD person) but so far it seem okay.
    Maybe I'll regret it in a while and try out another GUI. But at least I'm making (simple) stuff and got going.

    1 vote