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

如何将QQuickTextDocument指针从QML传递至Python?

问题

把Qt/C应用转成Python版本时遇到属性类型错误:原C代码通过带QML_ELEMENT的类,能正常将QQuickTextDocument*从QML传递到C++,但Python版本运行时报错:

/main.qml:15:9: Unable to assign QQuickTextDocument to [unknown property type]

推测是Python类无法识别QQuickTextDocument类型,因为它不属于QML的有效值类型。

原代码

C++类声明

class Createable01 : public QObject
{
    Q_OBJECT
    QML_ELEMENT
public:
    explicit Createable01(QObject *parent = nullptr);

signals:
    void textDocumentChanged();

public:
    Q_INVOKABLE void colorize(QQuickTextDocument *doc);

    QQuickTextDocument *m_textDocument;
    QQuickTextDocument *textDocument() const;
    void setTextDocument(QQuickTextDocument *newTextDocument);

private:
    Q_PROPERTY(QQuickTextDocument *doc READ textDocument WRITE setTextDocument NOTIFY
                   textDocumentChanged FINAL)
};

Python类实现(原错误版本)

class Creatable(QObject):
    name_changed = Signal()
    textDocument: QQuickTextDocument

    def __init__(self, ):
        QObject.__init__(self)

    def get_textDocument(self):
        return self.textDocument

    def set_textDocument(self, newTextDocument):
        self.textDocument = newTextDocument

    doc = Property(QQuickTextDocument, get_textDocument, set_textDocument)

QML文件

Window {
    height: 480
    title: qsTr("Hello World")
    visible: true
    width: 640

    Creatable {
        id: highlighter

        doc: textArea.textDocument
    }
    TextArea {
        id: textArea

        height: 400
        width: 400

        anchors {
            centerIn: parent
        }
    }
}
解决方案

问题根源是PySide/PyQt中直接将QQuickTextDocument声明为Property类型时,QML无法识别该类型。解决方法是改用QObject作为属性的公开类型(因为QQuickTextDocument继承自QObject),在Python内部再做类型判断和转换,同时确保属性带有notify信号以同步状态。

修改后的Python代码

from PySide6.QtCore import QObject, Property, Signal
from PySide6.QtQuick import QQuickTextDocument

class Creatable(QObject):
    # 定义属性变更的通知信号
    text_document_changed = Signal()
    _text_document = None

    def __init__(self, parent=None):
        super().__init__(parent)

    def get_text_document(self):
        return self._text_document

    def set_text_document(self, new_doc):
        if self._text_document != new_doc:
            self._text_document = new_doc
            self.text_document_changed.emit()

    # 用QObject作为属性对外类型,QML可正确识别
    doc = Property(QObject, get_text_document, set_text_document, notify=text_document_changed)

    # 示例处理方法:内部转换为QQuickTextDocument类型
    def colorize(self):
        if isinstance(self._text_document, QQuickTextDocument):
            # 获取底层的QTextDocument进行操作
            text_doc = self._text_document.textDocument()
            # 这里添加你的文本着色等逻辑

补充:Python类注册到QML

如果使用的是PySide6 6.5以下版本,需要在主函数中手动注册类到QML:

from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine
import sys

if __name__ == "__main__":
    app = QGuiApplication(sys.argv)
    engine = QQmlApplicationEngine()
    # 注册自定义类到QML模块
    engine.qmlRegisterType(Creatable, "CustomTypes", 1, 0, "Creatable")
    engine.load("main.qml")
    if not engine.rootObjects():
        sys.exit(-1)
    sys.exit(app.exec())

对应的QML文件需要添加导入语句:

import CustomTypes 1.0

Window {
    // 原QML内容不变
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 11:00:39