Receiving pyqtSignal from Singleton(从 Singleton 接收 pyqtSignal)
问题描述
python中有单例类:
There's singleton class in 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 Method 时,都应该发出一个信号,告诉所有实例数据从某个地方发生了更改,应该重新读取.
The idea is to have one single data store accessible from allover the program. Every time a set Method is called, a signal should be emitted telling all instances that from somewhere the data was changed and should be re-read.
很酷的计划,但是如果你看一下测试代码
Cool plan, but if you look at the test code
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)
而且控制台输出很奇怪(至少对我来说):
And the console output it get's strange (at least for me):
<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 没有收到信号......
Both instances do have the same address, cool the singleton does it's job. To ds1 if've connected the "dataChange" signal which works properly if from ds1 data is updated. BUT no signal is received by ds1 if I change the data with ds2.set......
有人对这里发生的事情有解释吗?数据在实例之间正确共享,但不是信号:-/
Does anybody have an explanation about what happens here. Data is shared properly across the instances, but not the signals:-/
推荐答案
虽然您的 Singleton 类遵守始终返回相同的对象,但这并不意味着它已正确实现,在您的情况下,在 new 中创建了新对象但是您返回创建的第一个对象(满足您显然想要的)但信号dataChanged"属于新对象而不是导致问题的第一个对象.这种情况下的解决方案是使用元类,因为这个库指出:
Although your Singleton class complies that the same object is always returned but that does not imply that it is correctly implemented, in your case in new the new object is created but you return the first object created (fulfilling what you apparently want) but the signal "dataChanged "belongs to the new object and not to the first object causing the problem. The solution in this case is to use metaclasses as this library points out:
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
这篇关于从 Singleton 接收 pyqtSignal的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:从 Singleton 接收 pyqtSignal
基础教程推荐
- 如何在海运重新绘制中自定义标题和y标签 2022-01-01
- 线程时出现 msgbox 错误,GUI 块 2022-01-01
- 在 Python 中,如果我在一个“with"中返回.块,文件还会关闭吗? 2022-01-01
- 用于分类数据的跳跃记号标签 2022-01-01
- 筛选NumPy数组 2022-01-01
- 如何让 python 脚本监听来自另一个脚本的输入 2022-01-01
- 何时使用 os.name、sys.platform 或 platform.system? 2022-01-01
- Dask.array.套用_沿_轴:由于额外的元素([1]),使用dask.array的每一行作为另一个函数的输入失败 2022-01-01
- 使用PyInstaller后在Windows中打开可执行文件时出错 2022-01-01
- Python kivy 入口点 inflateRest2 无法定位 libpng16-16.dll 2022-01-01