I'm using PySide to manage some hardware and perform some relatively simple operations depending on (e.g.) button clicks in the interface. The code for running each of these pieces of hardware resides in another thread. For convenience, to all of those hardware drivers I've added a generic invoke_method
signal, such that a UI component can use
my_driver.invoke_method.emit('method_name', [arg, ...], {kwarg, ...})
Obviously this accesses the signal attribute in that other thread directly.... but I'm not sure if this is necessarily okay in a GIL world.
If this is indeed too lazy a solution - are there any other great alternatives for invoking arbitrary methods in arbitrary threads without having to have an operation-specific signal in the UI connected to another signal in the driver?
I could imagine instead using a signal in each bit of UI code that accessed a different piece of hardware - something like do_invocation_driver_1
and do_invocation_driver_2
and connect those to the invoke_method
signal of the corresponding driver.
I'd recommend reading this post for a general approach to interface threads with a PyQt GUI. The post discusses a thread that does socket I/O, but this really is applicable to any thread. Specifically, hardware-interface threads usually also use I/O, so this may be a good fit.
The approach discussed is very generic, using Queue.Queue
, and may seem like an overkill for simple tasks (but I just want to call "that" function in a thread). However, once your application grows non-trivial, you will appreciate it, because it avoids any thread synchronization problems whatsoever, and is very scalable. I've personally used it to implement complex PyQt GUIs with side-threads doing all kinds of stuff.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With