PySide *any* 方法调用 - SIGNALs 和 SLOTs
PySide *any* method call - SIGNALs and SLOTs
我正在尝试为我的 PySide GUI 库创建简单、通用的方法调用:
class GUI(QApplication):
def __init__(self, *args, **kwargs):
super(GUI, self).__init__()
self.gui_signal = Signal()
self.gui_signal.connect(self.method_call)
插槽获取对象、方法并调用 object.method with args:
@Slot()
def method_call(self, obj, method_name, *args, **kwargs):
method = getattr(obj, method_name)
if method:
return method(*args, **kwargs)
else:
return None
这应该发出那个棘手的插槽:
def anymethod(self, obj, method_name, *args, **kwargs):
self.gui_signal.emit(obj, method_name, *args, **kwargs)
这是另一个工作线程,例如更新进度条
class MyApp(object):
...
def update_progress(self):
perc = (self.done * 100) / self.total
self.gui.anymethod(self.progressBar, 'setValue', int(perc))
我发现这种方法行不通,而且 args 的传递方式有误。我应该怎么做才能解决?
信号不应定义为 class 的成员,而应定义为 class 的属性。另一方面你必须注明签名,最后,字典不支持所以你必须将*args
,**kwargs
转换为元组。
from PySide import QtCore, QtGui
class GUI(QtGui.QApplication):
gui_signal = QtCore.Signal(object, str, tuple)
def __init__(self, *args, **kwargs):
super(GUI, self).__init__([])
self.gui_signal.connect(self.method_call)
@QtCore.Slot(object, str, tuple)
def method_call(self, obj, method_name, data):
if hasattr(obj, method_name):
method = getattr(obj, method_name)
args, kwargs = data
if hasattr(method, '__call__'):
method(*args, **kwargs)
def anymethod(self, obj, method_name, *args, **kwargs):
self.gui_signal.emit(obj, method_name, (args, kwargs))
class MyApp(object):
def __init__(self):
self.gui = GUI()
self.progressBar = QtGui.QProgressBar(maximum=100)
self.progressBar.show()
self.total = 200
self.done = 100
QtCore.QTimer.singleShot(300, self.update_progress)
def update_progress(self):
perc = (self.done * 100) / self.total
self.gui.anymethod(self.progressBar, 'setValue', int(perc))
def run(self):
return self.gui.exec_()
if __name__ == '__main__':
import sys
app = MyApp()
sys.exit(app.run())
我正在尝试为我的 PySide GUI 库创建简单、通用的方法调用:
class GUI(QApplication):
def __init__(self, *args, **kwargs):
super(GUI, self).__init__()
self.gui_signal = Signal()
self.gui_signal.connect(self.method_call)
插槽获取对象、方法并调用 object.method with args:
@Slot()
def method_call(self, obj, method_name, *args, **kwargs):
method = getattr(obj, method_name)
if method:
return method(*args, **kwargs)
else:
return None
这应该发出那个棘手的插槽:
def anymethod(self, obj, method_name, *args, **kwargs):
self.gui_signal.emit(obj, method_name, *args, **kwargs)
这是另一个工作线程,例如更新进度条
class MyApp(object):
...
def update_progress(self):
perc = (self.done * 100) / self.total
self.gui.anymethod(self.progressBar, 'setValue', int(perc))
我发现这种方法行不通,而且 args 的传递方式有误。我应该怎么做才能解决?
信号不应定义为 class 的成员,而应定义为 class 的属性。另一方面你必须注明签名,最后,字典不支持所以你必须将*args
,**kwargs
转换为元组。
from PySide import QtCore, QtGui
class GUI(QtGui.QApplication):
gui_signal = QtCore.Signal(object, str, tuple)
def __init__(self, *args, **kwargs):
super(GUI, self).__init__([])
self.gui_signal.connect(self.method_call)
@QtCore.Slot(object, str, tuple)
def method_call(self, obj, method_name, data):
if hasattr(obj, method_name):
method = getattr(obj, method_name)
args, kwargs = data
if hasattr(method, '__call__'):
method(*args, **kwargs)
def anymethod(self, obj, method_name, *args, **kwargs):
self.gui_signal.emit(obj, method_name, (args, kwargs))
class MyApp(object):
def __init__(self):
self.gui = GUI()
self.progressBar = QtGui.QProgressBar(maximum=100)
self.progressBar.show()
self.total = 200
self.done = 100
QtCore.QTimer.singleShot(300, self.update_progress)
def update_progress(self):
perc = (self.done * 100) / self.total
self.gui.anymethod(self.progressBar, 'setValue', int(perc))
def run(self):
return self.gui.exec_()
if __name__ == '__main__':
import sys
app = MyApp()
sys.exit(app.run())