Native OS widgets on every platform โ your app looks like it belongs on Windows, macOS or Linux.
wxPython is a set of Python bindings for the C++ wxWidgets library. Unlike Qt or Kivy, which draw their own widgets, wxWidgets maps each control to the host operating system's native API โ Win32/UWP on Windows, Cocoa on macOS, GTK on Linux. The result: your app genuinely looks and behaves like a native application on each platform.
wxPython has been around since 1998 and powers many long-lived desktop tools. Its API is more verbose than tkinter but offers significantly richer widgets and better platform integration (system tray, native file dialogs, accessibility).
MainLoop() to start.BoxSizer, GridSizer, FlexGridSizer handle layout (similar to Qt layouts).widget.Bind(wx.EVT_BUTTON, handler) connects events to functions.| Class | Purpose |
|---|---|
wx.Button | Clickable action |
wx.TextCtrl | Single or multi-line text |
wx.ListCtrl | Lists and tables |
wx.TreeCtrl | Tree views |
wx.Notebook | Tabbed pages |
wx.MenuBar / wx.ToolBar | Menus and toolbars |
wx.FileDialog | Native open/save dialogs |
pip install wxPython
# Verify:
python -c "import wx; print(wx.version())"
# Demo apps ship with wx:
python -m wx.lib.inspection
import wx
app = wx.App()
frame = wx.Frame(None, title="wxPython demo", size=(300, 160))
panel = wx.Panel(frame)
btn = wx.Button(panel, label="Say hi", pos=(20, 20))
btn.Bind(wx.EVT_BUTTON, lambda e: wx.MessageBox("Hello!"))
frame.Show()
app.MainLoop()
import wx
class FormFrame(wx.Frame):
def __init__(self):
super().__init__(None, title="Contact", size=(360, 200))
panel = wx.Panel(self)
grid = wx.FlexGridSizer(3, 2, 8, 8)
self.name = wx.TextCtrl(panel)
self.email = wx.TextCtrl(panel)
grid.AddMany([(wx.StaticText(panel, label="Name:"), 0), (self.name, 1, wx.EXPAND),
(wx.StaticText(panel, label="Email:"), 0), (self.email, 1, wx.EXPAND)])
grid.AddGrowableCol(1)
btn = wx.Button(panel, label="Save")
btn.Bind(wx.EVT_BUTTON, self.on_save)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(grid, 1, wx.ALL | wx.EXPAND, 12)
sizer.Add(btn, 0, wx.ALIGN_RIGHT | wx.ALL, 12)
panel.SetSizer(sizer)
def on_save(self, event):
wx.MessageBox(f"{self.name.GetValue()} / {self.email.GetValue()}")
app = wx.App()
FormFrame().Show()
app.MainLoop()
import wx
app = wx.App()
frame = wx.Frame(None, title="Tabs")
nb = wx.Notebook(frame)
page1 = wx.Panel(nb)
page2 = wx.Panel(nb)
nb.AddPage(page1, "Settings")
nb.AddPage(page2, "About")
wx.StaticText(page1, label="Configure here", pos=(20, 20))
frame.Show()
app.MainLoop()
pos= coordinates for resizable layouts.wx.Frame or wx.Panel for reusable UI components.wx.CallAfter() to update the UI from background threads safely.wx.glcanvas and wx.lib provide OpenGL and extended widgets.Native platform appearance is a priority and you target traditional desktop OSes. A strong alternative to Qt when you want native widgets without Qt's licensing concerns.
Useful guides and tools (from webpage_links.xlsx).