PySide/PyQt 中安全且惰性的方法调用
我使用 PySide 来管理一些硬件并根据(例如)界面中的按钮单击执行一些相对简单的操作。运行每个硬件的代码驻留在另一个线程中。为了方便起见,我为所有这些硬件驱动程序添加了一个通用的 invoke_method
信号,以便 UI 组件可以使用
my_driver.invoke_method.emit('method_name', [arg, ...], {kwarg, ...})
显然这会直接访问其他线程中的信号属性......但是我'我不确定这在 GIL 世界中是否一定可以。
如果这确实是一个太懒的解决方案 - 是否有任何其他很好的替代方案可以在任意线程中调用任意方法,而无需将 UI 中的特定于操作的信号连接到驱动程序中的另一个信号?
我可以想象在访问不同硬件的每一位 UI 代码中使用一个信号 - 例如 do_in Vocation_driver_1
和 do_invocau_driver_2
并将它们连接到 invoke_method< /code> 相应驱动程序的信号。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我建议阅读这篇文章< /a> 用于将线程与 PyQt GUI 连接的通用方法。这篇文章讨论了执行套接字 I/O 的线程,但这确实适用于任何线程。具体来说,硬件接口线程通常也使用 I/O,因此这可能是一个不错的选择。
所讨论的方法非常通用,使用 Queue.Queue,对于简单任务来说似乎有点过分了(但我只想在线程中调用“那个”函数)。然而,一旦您的应用程序变得不平凡,您就会欣赏它,因为它避免了任何线程同步问题,并且具有很强的可扩展性。我个人用它来实现复杂的 PyQt GUI,并通过侧线程执行各种操作。
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.