Last active
October 1, 2020 05:44
-
-
Save billyshambrook/9796603d0299b2bcd74d to your computer and use it in GitHub Desktop.
Debug Qt Signals with graph
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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