Python is a popular programming used for everything from scripting routine tasks to building websites and performing complex data analysis. While you can accomplish a lot with command line tools, some tasks are better suited to graphical interfaces. You may also find yourself wanting to build a desktop front-end for an existing tool to improve usability for non-technical users. Or maybe you're building some hardware or a mobile app and want an intuitive touchscreen interface.
To create graphical user interfaces with Python, you need a GUI library. Unfortunately, at this point things get pretty confusing -- there are many different GUI libraries available for Python, all with different capabilities and licensing. Which Python GUI library should you use for your project?
In this article, we will look at a selection of the most popular Python GUI frameworks currently available and why you should consider using them for your own projects. You'll learn about the relative strengths of each library, understand the licensing limitations and see a simple Hello, World! application written in each. By the end of the article you should feel confident choosing the right library for your project.
Tkinter
Best for simple tool GUIs, small portable applications
Tkinter is the defacto GUI framework for Python. It comes bundled with Python on both Windows and macOS. (On Linux, it may require downloading an additional package from your distribution's repo.) Tkinter is a wrapper written around the Tk GUI toolkit. Its name is an amalgamation of the words Tk and Interface.
Tkinter is a simple library with support for standard layouts and widgets, as well as more complex widgets such as tabbed views & progressbars. Tkinter is a pure GUI library, not a framework. There is no built-in support for GUIs driven from data sources, databases, or for displaying or manipulating multimedia or hardware. However, if you need to make something simple that doesn't require any additional dependencies, Tkinter may be what you are looking for. Tkinter is cross-platform however the widgets can look outdated, particularly on Windows.
Installation Already installed with Python on Windows and macOS. Ubuntu/Debian Linux sudo apt install python3-tk
A simple hello world application in Tkinter is shown below.
- Standard
- Class-based
import tkinter as tk
window = tk.Tk()
window.title("Hello World")
def handle_button_press(event):
window.destroy()
button = tk.Button(text="My simple app.")
button.bind("", handle_button_press)
button.pack()
# Start the event loop.
window.mainloop()
from tkinter import Tk, Button
class Window(Tk):
def __init__(self):
super().__init__()
self.title("Hello World")
self.button = Button(text="My simple app.")
self.button.bind("", self.handle_button_press)
self.button.pack()
def handle_button_press(self, event):
self.destroy()
# Start the event loop.
window = Window()
window.mainloop()
Hello world application built using Tkinter, running on Windows 11
Tkinter was originally developed by Steen Lumholt and Guido Van Rossum, who designed Python itself. Both the GUI framework and the language are licensed under the same Python Software Foundation (PSF) License. While the license is compatible with the GPL, it is a 'permissive' license (similar to the MIT License) that allows it to be used for proprietary applications and modifications.
PyQt or PySide
Best for desktop applications, multimedia, scientific and engineering software
PyQt and PySide are wrappers around the Qt framework. They allow you to easily create modern interfaces that look right at home on any platform, including Windows, macOS, Linux and even Android. They also have solid tooling with the most notable being Qt Creator, which includes a WYSIWYG editor for designing GUI interfaces quickly and easily. Being backed by a commercial project means that you will find plenty of support and online learning resources to help you develop your application.
Qt (and by extension PyQt & PySide) is not just a GUI library, but a complete application development framework. In addition to standard UI elements, such as widgets and layouts, Qt provides MVC-like data-driven views (spreadsheets, tables), database interfaces & models, graph plotting, vector graphics visualization, multimedia playback, sound effects & playlists and built-in interfaces for hardware such as printing. The Qt signals and slots models allows large applications to be built from re-usable and isolated components.
While other toolkits can work great when building small & simple tools, Qt really comes into its own for building real commercial-quality applications where you will benefit from the pre-built components. This comes at the expense of a slight learning curve. However, for smaller projects Qt is not really any more complex than other libraries. Qt Widgets-based applications use platform native widgets to ensure they look and feel at home on Windows, macOS and Qt-based Linux desktops.
Installationpip install pyqt6
or pip install pyside6
A simple hello world application in PyQt6, using the Qt Widgets API is shown below.
- PyQt6
- PySide6
from PyQt6.QtWidgets import QMainWindow, QApplication, QPushButton
import sys
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Hello World")
button = QPushButton("My simple app.")
button.pressed.connect(self.close)
self.setCentralWidget(button)
self.show()
app = QApplication(sys.argv)
w = MainWindow()
app.exec()
from PySide6.QtWidgets import QMainWindow, QApplication, QPushButton
import sys
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Hello World")
button = QPushButton("My simple app.")
button.pressed.connect(self.close)
self.setCentralWidget(button)
self.show()
app = QApplication(sys.argv)
w = MainWindow()
app.exec()
As you can see, the code is almost identical between PyQt & PySide, so it's not something to be concerned about when you start developing with either: you can always migrate easily if you need to.
Hello world application built using PyQt6, running on Windows 11
Before the Qt Company (under Nokia) released the officially supported PySide library in 2009, Riverbank Computing had released PyQt in 1998. The main difference between these two libraries is in licensing. The free-to-use version of PyQt is licensed under GNU General Public License (GPL) v3 but PySide is licensed under GNU Lesser General Public License (LGPL). This means that PyQt is limited GPL-licensed applications unless you purchase its commercial version, while PySide may be used in non-GPL applications without any additional fee. However, note that both these libraries are separate from Qt itself which also has a free-to-use, open source version and a paid, commercial version.
For a more information see our article on PyQt vs PySide licensing.
PyQt6
PySide6
PyQt5
PyQt/PySide with QML
Best for Raspberry Pi, microcontrollers, industrial and consumer electronics
When using PyQt and PySide you actually have two options for building your GUIs. We've already introduced the Qt Widgets API which is well-suited for building desktop applications. But Qt also provides a declarative API in the form of Qt Quick/QML.
Using Qt Quick/QML you have access to the entire Qt framework for building your applications. Your UI consists of two parts: the Python code which handles the business logic and the QML which defines the structure and behavior of the UI itself. You can control the UI from Python, or use embedded Javascript code to handle events and animations.
Qt Quick/QML is ideally suited for building modern touchscreen interfaces for microcontrollers or device interfaces -- for example, building interfaces for microcontrollers like the Raspberry Pi. However you can also use it on desktop to build completely customized application experiences, like those you find in media player applications like Spotify, or to desktop games.
Installationpip install pyqt6
or pip install pyside6
A simple Hello World app in PyQt6 with QML. Save the QML file in the same folder as the Python file, and run as normally.
- main.py
- main.qml
import sys
from PyQt6.QtGui import QGuiApplication
from PyQt6.QtQml import QQmlApplicationEngine
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
engine.quit.connect(app.quit)
engine.load('main.qml')
sys.exit(app.exec())
import QtQuick 2.15
import QtQuick.Controls 2.15
ApplicationWindow {
visible: true
width: 600
height: 500
title: "HelloApp"
Text {
anchors.centerIn: parent
text: "Hello World"
font.pixelSize: 24
}
}
Licensing for Qt Quick/QML applications is the same as for other PyQt/PySide apps.
PyQt
PySide
Hello world application built using PyQt6 & QML, running on Windows 11
Kivy
Best for Python mobile app development
While most other GUI frameworks are bindings to toolkits written in other programming languages, Kivy is perhaps the only framework which is primarily written in pure Python. If you want to create touchscreen-oriented interfaces with a focus on mobile platforms such as Android and iOS, this is the way to go. This does run on desktop platforms (Windows, macOS, Linux) as well but note that your application may not look and behave like a native application. However, there is a pretty large community around this framework and you can easily find resources to help you learn it online.
The look and feel of Kivy is extremely customizable, allowing it to be used as an alternative to libraries like Pygame (for making games with Python). The developers have also released a number of separate libraries for Kivy. Some provide Kivy with better integration and access to certain platform-specific features, or help package your application for distribution on platforms like Android and iOS. Kivy has it's own design language called Kv, which is similar to QML for Qt. It allows you to easily separate the interface design from your application's logic.
There is a 3rd party add-on for Kivy named KivyMD that replaces Kivy's widgets with ones that are compliant with Google's Material Design.
A simple hello world application in Kivy is shown below.
Installationpip install kivy
A simple hello world application in Kivy is shown below.
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.core.window import Window
Window.size = (300, 200)
class MainWindow(BoxLayout):
def __init__(self):
super().__init__()
self.button = Button(text="Hello, World?")
self.button.bind(on_press=self.handle_button_clicked)
self.add_widget(button)
def handle_button_clicked(self, event):
self.button.text = "Hello, World!"
class MyApp(App):
def build(self):
self.title = "Hello, World!"
return MainWindow()
app = MyApp()
app.run()
Hello world application built using Kivy, running on Windows 11
An equivalent application built using the Kv declarative language is shown below.
- main.py
- controller.kv
import kivy
kivy.require('1.0.5')
from kivy.uix.floatlayout import FloatLayout
from kivy.app import App
from kivy.properties import ObjectProperty, StringProperty
class Controller(FloatLayout):
'''Create a controller that receives a custom widget from the kv lang file.
Add an action to be called from the kv lang file.
'''
def button_pressed(self):
self.button_wid.text = 'Hello, World!'
class ControllerApp(App):
def build(self):
return Controller()
if __name__ == '__main__':
ControllerApp().run()
#:kivy 1.0
:
button_wid: custom_button
BoxLayout:
orientation: 'vertical'
padding: 20
Button:
id: custom_button
text: 'Hello, World?'
on_press: root.button_pressed()
The name of the Kv file must match the name of the class from the main application -- here Controller
and controller.kv
.
Hello world application built using Kivy + Kv, running on Windows 11
In February 2011, Kivy was released as the spiritual successor to a similar framework called PyMT. While they shared similar goals and was also led by the current core developers of Kivy, where Kivy differs is in its underlying design and a professional organization which actively develops and maintains it. Kivy is licensed under the MIT license, which is a 'permissive' license that allows you to use it freely in both open source and proprietary applications. As such, you are even allowed to make proprietary modifications to the framework itself.
PySimpleGUI
Best for quickly building UIs for simple tools, very portable
PySimpleGUI aims to simplify GUI application development for Python. It doesn't reinvent the wheel but provides a wrapper around other existing frameworks such as Tkinter, Qt (PySide 2), WxPython and Remi. By doing so, it not only lowers the barrier to creating a GUI but also allows you to easily migrate from one GUI framework to another by simply changing the import statement. While there is a separate port of PySimpleGUI for each of these frameworks, the Tkinter version is considered the most feature complete with the Qt version coming in at second. At the time of writing, the other ports are still more or less a work-in-progress.
There is a fair amount of good resources to help you learn to use PySimpleGUI, including an official Cookbook and a Udemy course offered by the developers themselves. According to their project website, PySimpleGUI was initially made (and later released in 2018) because the lead developer wanted a 'simplified' GUI framework to use in his upcoming project and wasn't able to find any that met his needs.
Installationpip install pysimplegui
import PySimpleGUI as sg
layout = [
[sg.Button("My simple app.")]
]
window = sg.Window("Hello World", layout)
while True:
event, values = window.read()
print(event, values)
if event == sg.WIN_CLOSED or event == "My simple app.":
break
window.close()
Hello world application built using PySimpleGUI, running on Windows 11
PySimpleGUI is licensed under the same LGPL v3 license as PySide, which allows its use in proprietary applications but modifications to the framework itself must be released as open source.
WxPython
Best for simple portable desktop applications
WxPython is a wrapper for the popular, cross-platform GUI toolkit called WxWidgets. It is implemented as a set of Python extension modules that wrap the GUI components of the popular wxWidgets cross platform library, which is written in C++.
WxPython uses native widgets on most platforms, ensure that your application looks and feels at home. However, WxPython is known to have certain platform-specific quirks and it also doesn't provide the same level of abstraction between platforms as Qt for example. This may affect how easy it is to maintain cross-platform compatibility for your application.
WxPython is under active development and is also currently being reimplemented from scratch under the name 'WxPython Phoenix'. The team behind WxWidgets is also responsible for WxPython, which was initially released in 1998.
Installationpip install wxpython
import wx
class MainWindow(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title=title, size=(200, -1))
self.button = wx.Button(self, label="My simple app.")
self.Bind(
wx.EVT_BUTTON, self.handle_button_click, self.button
)
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.button)
self.SetSizer(self.sizer)
self.SetAutoLayout(True)
self.Show()
def handle_button_click(self, event):
self.Close()
app = wx.App(False)
w = MainWindow(None, "Hello World")
app.MainLoop()
Hello world application built using WxPython, running on Windows 11
Both WxWidgets and WxPython are licensed under a WxWindows Library License, which is a 'free software' license similar to LGPL (with a special exception). It allows both proprietary and open source applications to use and modify WxPython.
PyGObject (GTK+)
Best for developing applications for GNOME desktop
If you intend to create an application that integrates well with GNOME and other GTK-based desktop environments for Linux, PyGObject is the right choice. PyGObject itself is a language-binding to the GTK+ widget toolkit. It allows you to create modern, adaptive user interfaces that conform to GNOME's Human Interface Guidelines (HIG).
It also enables the development of 'convergent' applications that can run on both Linux desktop and mobile platforms. There are a few first-party and community-made, third-party tools available for it as well. This includes the likes of GNOME Builder and Glade, which is yet another WYSIWYG editor for building graphical interfaces quickly and easily.
Unfortunately, there aren't a whole lot of online resources to help you learn PyGObject application development, apart from this one rather well-documented tutorial. While cross-platform support does exist (e.g. Inkscape, GIMP), the resulting applications won't feel completely native on other desktops. Setting up a development environment for this, especially on Windows and macOS, also requires more steps than for most other frameworks in this article, which just need a working Python installation.
Installation Ubuntu/Debian sudo apt install python3-gi python3-gi-cairo gir1.2-gtk-4.0
, macOS Homebrew brew install pygobject4 gtk+4
import gi
gi.require_version("Gtk", "4.0")
from gi.repository import Gtk
def on_activate(app):
win = Gtk.ApplicationWindow(application=app)
btn = Gtk.Button(label="Hello, World!")
btn.connect('clicked', lambda x: win.close())
win.set_child(btn)
win.present()
app = Gtk.Application(application_id='org.gtk.Example')
app.connect('activate', on_activate)
app.run(None)
Hello world application built using PyGObject, running on Ubuntu Linux 21.10
PyGObject is developed and maintained under the GNOME Foundation, who is also responsible for the GNOME desktop environment. PyGObject replaces several separate Python modules, including PyGTK, GIO and python-gnome, which were previously required to create a full GNOME/GTK application. Its initial release was in 2006 and it is licensed under an older version of LGPL (v2.1). While there are some differences with the current version of LGPL (v3), the license still allows its use in proprietary applications but requires any modification to the library itself to be released as open source.
Remi
Best for web based UIs for Python applications
Remi, which stands for REMote Interface, is the ideal solution for applications that are intended to be run on servers and other headless setups. (For example, on a Raspberry Pi.) Unlike most other GUI frameworks/libraries, Remi is rendered completely in the browser using a built-in web server. Hence, it is completely platform-independent and runs equally well on all platforms.
That also makes the application's interface accessible to any computer or device with a web browser that is connected to the same network. Although access can be restricted with a username and password, it doesn't implement any security strategies by default. Note that Remi is meant to be used as a desktop GUI framework and not for serving up web pages. If more than one user connects to the application at the same time, they will see and interact with the exact same things as if a single user was using it.
Remi requires no prior knowledge of HTML or other similar web technologies. You only need to have a working understanding of Python to use it, which is then automatically translated to HTML. It also comes included with a drag n drop GUI editor that is akin to Qt Designer for PyQt and PySide.
import remi.gui as gui
from remi import start, App
class MyApp(App):
def main(self):
container = gui.VBox(width=120, height=100)
# Create a button, with the label "Hello, World!"
self.bt = gui.Button('Hello, World?')
self.bt.onclick.do(self.on_button_pressed)
# Add the button to the container, and return it.
container.append(self.bt)
return container
def on_button_pressed(self, widget):
self.bt.set_text('Hello, World!')
start(MyApp)
Remi is licensed under the Apache License v2.0, which is another 'permissive' license similar to the MIT License. The license allows using it in both open source and proprietary applications, while also allowing proprietary modifications to be made to the framework itself. Its main conditions revolve around the preservation of copyright and license notices.
Hello world application built using Remi, running on Chrome on Windows 11
Conclusion
If you're looking to build GUI applications with Python, there is probably a GUI framework/library listed here that fits the bill for your project. Try and weigh up the capabilities & licensing of the different libraries with the scale of your project, both now and in the future.
Don't be afraid to experiment a bit with different libraries, to see which feel the best fit. While the APIs of GUI libraries are very different, they share many underlying concepts in common and things you learn in one library will often apply in another.
You are only limited by your own imagination. So go out there and make something!
For an in-depth guide to building GUIs with Python see my PyQt book.