Skip to content

Instantly share code, notes, and snippets.

@billyshambrook
Last active October 1, 2020 05:44
Show Gist options
  • Save billyshambrook/9796603d0299b2bcd74d to your computer and use it in GitHub Desktop.
Save billyshambrook/9796603d0299b2bcd74d to your computer and use it in GitHub Desktop.
Debug Qt Signals with graph
import functools
import inspect
import graphviz
from PyQt4 import QtCore
from PyQt4 import QtGui
class MyGraph(object):
def __init__(self):
self.dot = graphviz.Digraph()
def add_node(self, sender, signal, slot):
self.dot.edge(sender, signal)
self.dot.edge(signal, slot)
def render(self):
self.dot.render('test.png', view=True)
my_graph = MyGraph()
def log_manual_slot(f):
"""
Decorate functions that are passed to the signal 'connect' method.
Example:
>>> mysignal.connect(log_manual_slot(myslot))
"""
@functools.wrap(f)
def wrapper(*args, **kwargs):
signal_name = inspect.stack()[1][0].f_code.co_names[-2]
sender = str(inspect.stack()[1][3])
logger.debug('{0}{1} emitted by {2} and picked up by {3}'.format(
signal_name,
args,
sender,
f.__name__)
my_graph.add_node(sender, signal_name, f.__name__)
return f(*args)
return wrapper
def log_automatic_slot(f):
""" Decorate 'pyqtSlot' decorated methods. """
@functools.wrap(f)
def wrapper(*args, **kwargs):
_, signal_name = f.__name__.rsplit('_', 1)
sender = str(args[0].sender())
logger.debug('{0}{1} emitted by {2} and picked up by {3}'.format(
signal_name,
args[1:],
sender,
f.__name__)
my_graph.add_node(sender, signal_name, f.__name__)
return f(*args)
return wrapper
class MainWindow(QtGui.QMainWindow):
updated = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.button = QtGui.QPushButton('My button', self)
self.button.setObjectName('mybutton')
QtCore.QMetaObject.connectSlotsByName(self)
@log_automatic_slot
@QtCore.pyqtSlot()
def on_mybutton_clicked(self):
self.updated.emit('hello, world!')
def update_recv(data):
1 + 1
def update_recv2(data):
1 + 1
if __name__ == '__main__':
import sys
app = QtGui.QApplication([])
view = MainWindow()
view.updated.connect(log_manual_slot(update_recv))
view.updated.connect(log_manual_slot(update_recv2))
view.show()
app.exec_()
my_graph.render()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment