You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法将Python函数绑定到QML按钮,运行报错求排查

Qt Quick前后端绑定报错:TypeError: Property 'greet' of object QVariant(PySide::PyObjectWrapper, ...) is not a function

问题场景

我在尝试绑定Qt Quick应用前后端时遇到问题,以下是我的示例代码,其中greet函数无参数,仅输出‘Hello from backend’。

原代码

main.py

from pathlib import Path
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine, QmlElement
from PyQt6.QtCore import QObject, pyqtSignal, pyqtSlot
import sys  # 原代码遗漏sys导入,此处补充

class Calculator(QObject):
    def __init__(self):
        QObject.__init__(self)

    @pyqtSlot()
    def greet(self):
        print("Hello from backend")

if __name__ == "__main__":
    app = QGuiApplication(sys.argv)
    engine = QQmlApplicationEngine()
    backend = Calculator()
    engine.rootContext().setContextProperty("backend", backend)
    engine.load("main.qml")

    engine.quit.connect(app.quit)
    sys.exit(app.exec_())

main.qml

import QtCore
import QtQuick
import QtQuick.Controls
import QtQuick.Dialogs

ApplicationWindow {
    id: mainWindow    
    width: 640
    height: 480
    visible: true  // 补充窗口显示必要属性

    Button { 
        objectName: "checkButton"
        id: modelCheck
        text: qsTr("Check model")
        onClicked: backend.greet()
    }
     
    Connections {
        target: backend
        function onSignalPrintTxt(boolValue) {
            return
        }
    }     
}

运行报错

TypeError: Property 'greet' of object QVariant(PySide::PyObjectWrapper, 0x1006571f0) is not a function

错误原因及修正

核心问题:混用PySide6和PyQt6模块

你同时导入了PySide6的GUI/QML模块,又导入了PyQt6的核心模块(QObject、pyqtSlot等),这两个是独立的Qt Python绑定库,不能混合使用,否则会导致槽函数无法被QML正确识别。

修正方案

统一使用PySide6的模块,并替换PyQt6的装饰器为PySide6对应的版本:

修正后的main.py

from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtCore import QObject, Slot  # 使用PySide6的Slot装饰器
import sys
from pathlib import Path

class Calculator(QObject):
    def __init__(self):
        super().__init__()  # 更简洁的父类初始化方式

    @Slot()  # 替换为PySide6的Slot装饰器
    def greet(self):
        print("Hello from backend")

if __name__ == "__main__":
    app = QGuiApplication(sys.argv)
    engine = QQmlApplicationEngine()
    backend = Calculator()
    engine.rootContext().setContextProperty("backend", backend)
    
    # 用绝对路径加载qml,避免工作目录导致的路径问题
    qml_file = Path(__file__).parent / "main.qml"
    engine.load(qml_file.resolve())

    if not engine.rootObjects():
        sys.exit(-1)

    engine.quit.connect(app.quit)
    sys.exit(app.exec_())

额外说明

  1. 补充了原代码遗漏的sys模块导入;
  2. 使用super().__init__()替代QObject.__init__(self),符合Python编码规范;
  3. 改用绝对路径加载QML文件,避免因运行环境工作目录不同导致的文件找不到问题;
  4. 增加engine.rootObjects()检查,方便快速排查QML加载失败情况。

内容的提问来源于stack exchange,提问作者Philipp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 17:10:29