首页 > 解决方案 > decorator on slot (PyQt)

问题描述

I use QT to build my GUI, and decorator to record the log. When I use the decorator on a slot, the GUI will crush.

The code is:

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *


def LogInfos(func):

    def wrapper(*s, **gs):
        print('log')
        ret = func(*s, **gs)
        return ret

    return wrapper
class Window(QWidget):
    def __init__(self):
        super(Window, self).__init__()
        layout = QHBoxLayout(self)
        btn = QPushButton('test')
        layout.addWidget(btn)
        btn.clicked.connect(self.testSlot)

    @LogInfos
    def testSlot(self):
        print('test slot')


@LogInfos
def testLog():
    print('test log')

if __name__ == '__main__':

    testLog()

    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

I has tested that the decorator function is OK, and the GUI is ok after remove the decorator.

标签: pythonpyqtpyqt5decoratorqt-signals

解决方案


See @ekhumoro's explanation of why, but using the decorated method in the slot is causing your problem due to an incorrect signature.

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *


def LogInfos(func):

    def wrapper(*s, **gs):
        print('log')
        ret = func(*s, **gs)
        return ret

    return wrapper
class Window(QWidget):
    def __init__(self):
        super(Window, self).__init__()
        layout = QHBoxLayout(self)
        btn = QPushButton('test')
        layout.addWidget(btn)
        btn.clicked.connect(self.testSlot)

    @LogInfos
    def testSlot(self, checked=False):
        print('test slot')


@LogInfos
def testLog():
    print('test log')

if __name__ == '__main__':

    testLog()

    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

推荐阅读