TL;DR; How to solve problems that should already have been solved vs. reinventing the wheel.
I have been programming in Python for a few years now. I like the amazing libraries it has, plus the power of the language. I dislike that it has weak typing.
In the languages I’ve used in the past, you declare a variable before you use it.
int integerVar;
double floatingPointVar;
Python doesn’t do it that way.
integerVar = 5
floatingPointVar = 5.0
The issue is that you can assign 3.1415 to integerVar and python will let you do that. I’ve recently learned about “TypedDict” which gives me structures and a package called “trycast”. I finally have the types of data structures I want from more structured languages, in python.
Add to that my discovery of the Language Server Protocol, which has turned Emacs into an IDE and interactive debugger, and my life is much, much better.
All of this was just a side project on top of what I was really doing, writing a tool to help teach English as a Second Language, or ESL.
The first day I did this, I had my e-reader program running. I had Google dictionary available. I had to open a Google meet, then share different screens, as needed, to show the different parts.
I had a markdown editor open to have words that I planned to pre teach. It was painful. Switching from one student to another was a good 5 minutes. Prep time was 30 minutes per 30-minute session.
The cure was clear, write my own tool to perform what I required. The framework I chose to use was Qt6. It has Python libraries, I was already using it for other tools. It should all just work.
First, I had to learn the format of EPub. From there I needed to import the book and prepare it to present. I decided to use a QTextEdit. This worked ok. It was nothing more than a weak version of the E-Reader I had been using.
What made it powerful, was that I could select a word in the QTextEdit. With the click of a button, pull up a definition.
I used the request package for my networking.
Over the following weeks, the tool got better and better. Combined with PipeWire and Open Broadcast Studio, I had a pretty clean interface. I could select a word, click the “define” button, the tool would check to see if we already had the definition, if not, it would fetch the definition from a remote server. It would then format everything and put it into its own QTextEdit and display the results.
My students liked it.
The problems started when I decided I wanted to be able to play a pronunciation. This required learning how to create a virtual microphone. Learning how to use the QMediaPlayer. Learning how to direct sound from my tool to the virtual microphone. Making sure that the patch was correctly created to send all the audio to the correct places.
I got that working.
Did you know that some words have multiple pronunciations? I did. I didn’t code for it. This is no real issue, I just need to connect a click on a button in the QTextEdit and when the signal is received, play the sound.
Do you know what you can’t put in a QTextEdit? That’s right, a button.
The QTextBrowser gives me clickable links, but those are not generating the types of signals I was looking for. Worse, I can’t use the CSS to format my text the way I want to.
There was only one thing to do. Roll my own. I needed to create my own wheel. I had to reinvent my own text browser widget.
Which took me to learning how to do low-level graphics in Qt.
As I dug through this mess, I found that built in tools that “just worked”. Which lead me to discovering I didn’t need my own settings/preferences system. Qt has QSettings which does everything I need plus more. That’s a win. I haven’t switched to it yet, but I will.
Having found QSettings, it occurred to me that Qt might have networking tools. I was just about to implement a caching system when that networking might be a part of QT struck me. Turns out that not only does Qt have a networking implementation, it has a caching networking implementation.
At the same time all of this is happening, I’ve gotten an API key from Merriam-Webster. I now have access to better dictionary information. And the data payload is entirely different. It is very complex. Three weeks of coding, and I’m at the 90% state.
This brings me back to “This must be a solved problem.” What is that problem? Drawing text that wraps.
Consider a logical line of text, 200 characters long. If your display is 80 characters wide, it will display 80 characters, 80 characters, 40 characters.
This would look bad. What you want to do is to find the first logical word break before the 81st character and break the line there. This is what your text editor does. This is what your browser is doing right now. Unless I type a very long word, your browser is moving to the next line between words.
Yes, QT has an option for doing exactly that type of word wrap. It looks great. It is precisely what I want to see.
It works perfectly until I need to start that logical line at someplace apart from the first character of the line.
Consider this text: specifically : the procedure of submitting a statement to such conditions or operations as will lead to its proof or disproof or to its acceptance or rejection.
This bit of text has three separate parts. The first part is in italics, the next is bold, and the rest is in standard text.
It is that long bit of text that I want to wrap. The issue is that the text exists within two different bounding boxes.
The first box exists from : to the edge of the window. The second bounding box exists from below the first line of text and spans from the left indent to the right edge of the window.
Qt either doesn’t have that option, or I have not found it.
So the next thing that could happen is for the code to provide me a way of determining where Qt is braking words. If I know that, then I can break the text into two parts and make this all work.
3 steps forward, 2 steps back.
The only thought I had as I read this was, “What language does awa use when he dreams at night, and does he talk in his sleep?”
It’s not so much that Python has weak typing but rather that it has runtime typing rather than compile time typing (or a feeble approximation thereof, in the case of C). I can live with that. I really like the fact that types and functions are objects, and can be handled just as integers can be. Metaclasses are fun.
If you want an alternative to Qt, take a look at WxPython, the Python wrapper for the open source WxWidgets graphics toolkit.