如何将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
相关产品推荐
相关产品推荐

