python中有单例类:
from PyQt5.QtCore import QObject, pyqtSignal
import logging
class Singleton(QObject):
_instance = None
def __new__(cls, *args, **kwargs):
if not isinstance(cls._instance, cls):
cls._instance = QObject.__new__(cls, *args, **kwargs)
return cls._instance
class DataStatus(Singleton, QObject):
'''
'''
dataChanged = pyqtSignal(str)
__val = 'init'
def __init__(self):
super().__init__()
def setVal(self, val):
self.dataChanged.emit('emit: ' + val)
logging.debug('emit: ' + val)
self.__val = val
def getVal(self):
return self.__val
这个想法是让整个程序都可以访问一个单一的数据存储。每次调用 set 方法时,都应发出一个信号,告诉所有实例数据已从某处更改并应重新读取。
很酷的计划,但是如果你看一下测试代码
def test(self):
self.ds1 = DataStatus()
self.ds1.dataChanged.connect(self.windowaction)
print(self.ds1)
print(self.ds1.getVal())
self.ds1.setVal('ds1.first')
self.ds2 = DataStatus()
#self.ds2.dataChanged.connect(self.windowaction)
print(self.ds2)
print(self.ds2.getVal())
self.ds2.setVal('ds2.second')
print(self.ds1.getVal())
def windowaction(self, q):
print(q)
控制台输出很奇怪(至少对我而言):
<DataStatus.DataStatus.DataStatus object at 0x03207580>
init
emit: ds1.first
<DataStatus.DataStatus.DataStatus object at 0x03207580>
ds1.first
ds2.second
两个实例确实有相同的地址,很酷的单例完成了它的工作。 到 ds1,如果连接了“dataChange”信号,如果来自 ds1 的数据被更新,该信号可以正常工作。 但是如果我用 ds2.set 更改数据...... ds1 没有收到任何信号......
有人对这里发生的事情有解释吗?数据在实例之间正确共享,但信号不是:-/
最佳答案
尽管您的 Singleton 类遵守始终返回相同对象的规定,但这并不意味着它已正确实现,但在您的情况下,在 new 中创建了新对象,但您返回了创建的第一个对象(满足您显然想要的)但是信号“dataChanged”属于新对象,而不属于引起问题的第一个对象。这种情况下的解决方案是使用元类作为 this library指出:
class Singleton(type(QObject), type):
def __init__(cls, name, bases, dict):
super().__init__(name, bases, dict)
cls._instance = None
def __call__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__call__(*args, **kwargs)
return cls._instance
class DataStatus(QObject, metaclass=Singleton):
dataChanged = pyqtSignal(str)
__val = "init"
def __init__(self):
super().__init__()
def setVal(self, val):
self.dataChanged.emit("emit: " + val)
logging.debug("emit: " + val)
self.__val = val
def getVal(self):
return self.__val
关于python - 从 Singleton 接收 pyqtSignal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59459770/