在PyQt5中使用QThreads之间的setattr

时间:2017-09-20 10:47:23

标签: python multithreading lambda pyqt pyqt5

我有一个包含两个主要类的程序:

  • 继承自QWidget的GUI类,具有多个用户输入和输出字段(图形,旋转框等)。
  • 一个Serial Monitor类,它继承自QObject并包含各种循环,用于根据一组参数(采样周期,轮询命令等)连续轮询串行连接设备。

Serial Monitor类的一个实例是从GUI类中创建的,并移动到辅助线程,如下所示:

    # Create Serial monitor instance in this thread
    self.serial_monitor = Serial_Monitor(
        formatter=self.poll,
        prompt="2 poll\n")

    # Create a secondary QThread to run the serial monitor
    self.serial_thread = QThread()

    # Move the serial monitor to the secondary thread and start
    self.serial_monitor.moveToThread(self.serial_thread)
    self.serial_thread.start()

当尝试将用户界面项(旋转框,按钮等)的输出直接传递给串行监视器中的变量时,我的问题出现了。我的主要目标是:

  • 我想避免在串行监视器中创建几个pyqtSlot函数,只是为了设置每个变量,因为它使得添加更多变量变得更加困难并使代码膨胀。

  • 我还想将串行监视器变量的所有设置保存在正确的线程中,而不是在GUI命令线程中设置它们。

我从GUI直接设置变量的初始解决方案是:

self.set_box_period.valueChanged.connect(
        lambda val: setattr(self.serial_monitor, "sample_period", val))

它避免在串行监视器中创建任何新方法,并且似乎设置变量就好了,但是我不确定它是否是“线程安全的”,而且还不确定如何查找。

经过一番挖掘后,我发现你可以像这样在类中重新实现__setattr__方法:

@pyqtSlot()
def __setattr__(self, name, value):
    """
    ------------------------------------------------------------------------
    Re-implementation of "getattr" method to correctly wire up to slots
    ------------------------------------------------------------------------
    """
    self.__dict__[name] = value
    self.logger.info(F"Set {name} to {value}")

日志输出表明每个串行监视器变量都在串行监视器线程中设置,因此该解决方案确实有效,但我不确定是否有必要。

总结一下,我是否需要担心在我的Serial Monitor类中重新实现__setattr__,或者我的初始lambda实现是否完全可以安全使用?

提前致谢!

0 个答案:

没有答案
相关问题