QMetaObject::invokeMethod: 没有这样的方法 signal_emitter::solve

QMetaObject::invokeMethod: No such method signal_emitter::solve

我正在尝试使用 pyqt5 对回溯算法进行可视化,并且我制作了一个 class 以在 GUI 中进行更新时发出信号,但每当我尝试调用该方法时发出信号我得到一个错误,那是因为我使用 QtCore.QMetaObject.invokeMethod 来调用该方法,从我发现的情况来看,这个方法只调用 qt 已知的槽和方法,从 that question 我发现我可以使用 Q_INVOKABLE 来解决这个问题,但我仍然不知道如何在 python 中做到这一点,这里是发出信号的 class:

class signal_emitter(QtCore.QObject):
    answer_signal = QtCore.pyqtSignal(int, int, str)

    def solve(self, grid, row, column):
        row, column = find_empty_cell(grid, row)

        if (row, column) == (None,None):
            return True

        for num in range(1, 10):
            if valid_row(grid[row], num
                ) and valid_column(grid, column, num
                ) and valid_box(grid, row, column, num):

                grid[row][column] = num     
                self.answer_signal.emit(row, column, str(num))

                if self.solve(grid, row, column):
                    return True
 
                grid[row][column] = 0
                self.answer_signal.emit(row, column, "0")

        return False

到目前为止,代码中的所有内容都很好,只是我无法在代码片段中调用名为 (solve) 的方法,因此我需要一种使用 Q_INVOKABLE 的方法或对 class 这样我就可以调用一个槽方法来调用 solve 提前致谢

对于 pyqt5,你必须使用 pyqtSlot 装饰器:

import random
from PyQt5 import QtCore


class signal_emitter(QtCore.QObject):
    answer_signal = QtCore.pyqtSignal(int, int, str)

    @QtCore.pyqtSlot(list, int, int, result=bool)
    def solve(self, grid, row, column):
        print("solve", grid, row, column)

        self.answer_signal.emit(1, 1, "foo")

        return random.choice([True, False])


obj = signal_emitter()
grid = [[1, 2], [3, 4]]
row = 0
column = 0

result = QtCore.QMetaObject.invokeMethod(
    obj,
    "solve",
    QtCore.Qt.DirectConnection,
    QtCore.Q_RETURN_ARG(bool),
    QtCore.Q_ARG(list, grid),
    QtCore.Q_ARG(int, row),
    QtCore.Q_ARG(int, column),
)

print(result)

输出:

solve [[1, 2], [3, 4]] 0 0
True