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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!
如何将函数绑定到 Qt 菜单栏中的操作?How to bind a function to an Action from Qt menubar?(如何将函数绑定到 Qt 菜单栏中的操作?)
PyQt 启动后进度跃升至 100%PyQt progress jumps to 100% after it starts(PyQt 启动后进度跃升至 100%)
如何将 yaxis 刻度标签设置在固定位置,以便当我How to set yaxis tick label in a fixed position so that when i scroll left or right the yaxis tick label should be visible?(如何将 yaxis 刻度标签设
`QImage` 构造函数有未知关键字 `data``QImage` constructor has unknown keyword `data`(`QImage` 构造函数有未知关键字 `data`)
将 x 轴刻度更改为自定义字符串Change x-axis ticks to custom strings(将 x 轴刻度更改为自定义字符串)
如何在python中将文件保存为excel时显示进度条?How to show progress bar while saving file to excel in python?(如何在python中将文件保存为excel时显示进度条?)