Reputation: 610
I am trying to create simple, universal method call for my PySide GUI library:
class GUI(QApplication):
def __init__(self, *args, **kwargs):
super(GUI, self).__init__()
self.gui_signal = Signal()
self.gui_signal.connect(self.method_call)
Slot to get object, method and 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
This should emit that tricky slot:
def anymethod(self, obj, method_name, *args, **kwargs):
self.gui_signal.emit(obj, method_name, *args, **kwargs)
This is some another working thread, which for example, updates progressbar
class MyApp(object):
...
def update_progress(self):
perc = (self.done * 100) / self.total
self.gui.anymethod(self.progressBar, 'setValue', int(perc))
I see this approach doesn't work and args are passed wrong way. What should I do to fix?
Upvotes: 1
Views: 633
Reputation: 243937
The signals should not be defined as members of the class but as attributes of the class. On the other hand you must indicate the signature, and lastly, the dictionaries do not support so you have to transform *args
, **kwargs
into a tuple.
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())
Upvotes: 1