Today was a major milestone: I got Pygame to render in a Qt-powered window! Here’s how.
First things first, I did keep to my word and started the day by “thinking slow”, reading in-depth documentation regarding the behavior of Python with regards to processes and threads (the threading was surprising!).
See, with the Global Interpreter Lock, known to seasoned Pythonistas as the GIL, your threads will only execute one at a time (so much for getting experience with threads…).
As I understand it, this exists mainly to offer certain guarantees about memory safety, which has me missing Rust just a wee bit, but hey, the situation is workable. I mean, you can use threads for I/O-bound tasks, and use the
multiprocessing module for CPU-intensive stuff.
That’s the short version, anyway. There’s really quite a few ways to run code concurrently in Python, including, but not limited to:
osmodule and raw process spawning
You get the idea.
What I ended up using is the
multiprocessing module, making use of the
Pipe classes to spawn a new process and send messages back and forth between parent process and child process.
This turned out to be way simpler than I thought. For one, I didn’t need the
multiprocessing.shared_memory stuff like I thought I did, which rules out all sorts of funky lock scenarios that I don’t even care to get into.
I pretty much just spawned a process by feeding it a
target function, which it would run when started. This process would receieve a
child_connection variable that I pass to it (created by the
Back in the parent process, I had a parent connection object as well, and I could send or receive data using either connection (using the default duplex piping).
I might need to set up an
asyncio client/server model, to send more complex messages…right now I basically have a catch-all
recv function that receives all the things that are sent. That’s fine for frame data, and it works fast, but it’s not exactly what I need for the rest of the program.
At least now, I know generally what I need to proceed:
- Forward the key events from Qt to pygame to move the character
- Create a slider for e.g. walking speed in Qt
- When that slider changes its value, configure the pygame process
That should be enough to keep me going for the next week or so, as I feel my way around Python. I have a book coming, at least: Fluent Python, by Luciano Ramalho. Hopefully, that can help shed some light on some of the corners of Python that are less-discussed in the documentation.
Mind you, I would not call Python “poorly documented”. In fact, it’s right up there with Rust as one of the best-documented langauges available. Just wanted to make that clear.
Rather, I’m learning many APIs at once: the Python standard library, the pygame API, and Qt. The standard library is pretty great – the others do a good job of explaining the fundamentals, don’t get me wrong, I just think I’m doing something weird that the documentation authors haven’t really considered as something worth documenting. That’s my fault, not theirs.
So I continue on my journey, stumbling through the brambles of unfamiliar territory. Will our caped crusader leap from the serpentine swamp, and find success? Find out tomorrow, same bat-time, same bat-channel!