插槽上的装饰器 (PyQt)

decorator on slot (PyQt)

我用QT构建我的GUI,用decorator来记录日志。当我在插槽上使用装饰器时,GUI 会崩溃。

密码是:

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_())

我测试过装饰器功能正常,去掉装饰器后界面正常

请参阅@ekhumoro 对原因的解释,但由于签名不正确,在槽中使用装饰方法导致了您的问题。

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_())

尝试一下:btn.clicked.connect(lambda: self.testSlot())

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)
        btn.clicked.connect(lambda: 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_())