修改__class__属性和PyQt信号以构建状态机

时间:2018-02-02 23:31:40

标签: python class inheritance pyqt signals

我正在构建一个简单的状态机,它操纵__class__属性来识别我们所处的状态。这遵循" Python Cookbook,D.Beazley"中的食谱8.19。问题是当我将此配方与PyQt信号一起使用时,状态机无法跟踪它所属的__class__

以下是我正在编写的状态机Interface的简化:

from PyQt5 import QtCore, QtWidgets

class Interface:
    def __init__(self):
        self.new_state(DisabledState)

    def enable(self):
        raise NotImplementedError

    def disable(self):
        raise NotImplementedError

    def new_state(self, newstate):
        self.__class__ = newstate


class EnabledState(Interface):
    def enable(self):
        print('enable/enabled state')

    def disable(self):
        print('disable/enabled state')
        self.new_state(DisabledState)


class DisabledState(Interface):
    def enable(self):
        print('enable/disabled state')
        self.new_state(EnabledState)

    def disable(self):
        print('disable/disabled state')

当我启用时,然后禁用此状态机:

class Thread(QtCore.QObject):
enable = QtCore.pyqtSignal()
disable = QtCore.pyqtSignal()

def __init__(self):
    super().__init__()
    self.interface = Interface()
    self.enable.connect(self.interface.enable)
    self.disable.connect(self.interface.disable)

myThread = Thread()
app = QtWidgets.QApplication([])
myThread.enable.emit()
myThread.disable.emit()
app.exec_()

在上面的代码中,我首先启用禁用的接口并转到启用状态。然后从启用状态我禁用接口,因此预期的输出是:

# enable/disabled state
# disable/enabled state

但是,我得到以下内容,interface似乎从未进入enabled州。

# enable/disabled state
# disable/disabled state

任何人都可以向我解释这里发生了什么吗?

P.S。 本书描述了另一个不需要修改__class__属性而没有继承的配方。那个食谱确实给出了正确的输出...

1 个答案:

答案 0 :(得分:1)

当您将self.interface.enable传递给.connect()时,它会引用DisabledState.enable,因此它的行为总是像被禁用一样。要解决此问题,您可以lambda: self.interface.enable()使用disable,类似num_rows = 3 num_columns = 3 random_matrix = numpy.random.random((num_rows, num_columns))