Headaches with wxPython 4.2.1

18 July 2023
Historically wxWidgets/wxPython has been my GUI toolkit of choice and in the past installing wxPython was just a matter of creating a virtual environment followed by doing a pip install wxpython within it. However having over the last week or so dug up some wxPython based code trying to get it working was throwing up all sorts of errors, typically involving libwx_gtk3u_html-3.2.so.0 and more often than not _ZN12wxWindowBase14RegisterHotKeyEiii being an undefined symbol. TL;DR I did eventually get it working but after all the hoops that needed jumping through one wonder if there is something amiss with the project.

Background

Historically wxWidgets/wxPython has been my GUI toolkit of choice and have been aware of it since when it was formally known as wxWindows. Although it is C++ based it kept itself to a fairly conservative subset of Classic C++ and its API documentation is such that finding out information is very quick and easy. In contrast the documentation for GTK bindings for languages other than its native C is a right pain, and as well as going full-on with Modern C++ Qt is more or less its own ecosystem complete with build tools; Win32 API together with Windows Forms while nice to use are — leaving aside the caveat of Wine — basically Microsoft Windows only, and Java's chunkiness has historically made me hate its entire development kit. The old wxPython code I was trying to run was a utility called wxLED — not to be confused by the widget of the same name — for constructing display sequences for LED dot-matrix displays.

Screenshot of wxLED

From memory the utility was pretty much complete but the associated electronics project of building a full LED display using my LED ‘tiles’ had fallen by the wayside and was something I was considering reviving, but then there was trouble getting the utility to run on any system I had access to. The final straw was trying to install wxPython via pip on a machine that had no previous trace of either wxPython or wxWidgets on it, yet it complained about a missing wxWidgets library even though wxPython includes a full copy of the wxWidgets code-base. If it cannot get this situation right then something is very wrong with the project — if it is down to a missing dependency then either the build should fail or the relevent features disabled. I did eventually get things working but not before starting a reimplemention using GTK.

Previous frustrations

In the past I had written an electronics stock tracking tool called wxCatalogue that made very tight usage of the wxDataViewCtrl widget and it had issues that were borderline-showstoppers for the application. Development involved making a a switch from wxPython to native wxWidgets because the wxPython version of the widget was even more broken and it became apparent that changes in the underlying wxWidgets take their time to filter through to the Python bindings. Eventually the core part of the application was rewritten using GTK and its underlying GTK TreeView widget, partly as an experiment in seeing what GTK was like in Python 3 compared to Python 2, and while figuring out how GTK under Python 3 operates was a right pain but once things got as far as having GTK's TreeView widget working I looked into fixing wxWidgets's GTK back-end. After frustrations trying to submit patches that would fix wxWidget's version of the dataview I ended up abandoning wxWidgets.

Screenshot of wxCatalogie

Eventually working

I was eventually able to get wxPython working and able to run my application but by any measure it was jumping through hoops. It involved doing a tarball install of the latest wxPython and then doing an old-style build.sh script build/install of wxPython with custom parameters, complete with having to fiddle around with environment variables. The shell commands shown below give an overview of the process:

cd wxWidgets-3.2.2.1 ./configure --prefix=/opt/wxWidgets/3.2.2.1/shared make -j4 make install export PATH=/opt/wxWidgets/3.2.2.1/shared/bin:$PATH cd .. python3 -m venv VirtEnv-wxPython . ./VirtEnv-wxPython/bin/activate cd wxPython-4.2.1 python3 build.py --use_syswx build_py python3 build.py --use_syswx install_py pip install pyopengl cd .. export LD_LIBRARY_PATH=/opt/wxWidgets/3.2.2.1/shared/lib/

The --use_syswx uses whatever wx-config it finds first so the wxPython is coaxed into using my custom wxPython build. On Slackware I suspect the wxPython and wxWidgets SlackBuilds are creating subtly different libraries, so it worth adding this parameter to the wxPython script to force it to use the wxWidgets libraries rather than building its own.

Remarks

I am two minds whether I would want to use wxWidgets or wxPython in a future project or whether to move over to GTK completely, especially since wxWidgets uses GTK as a backend on Linux and I am trying to avoid C++ entirely. When actually working wxWidgets has some higher-level widgets that GTK does not such as wxPropertyGrid and overall I consider it easier to use, but getting it working has been a massive irritation.