QVector自定义类作为Qt QML ListView模型无内容显示问题
问题:自定义类的QVector无法作为QML ListView模型显示内容
我尝试将自定义类的QVector绑定为QML ListView的模型,但屏幕无任何内容显示。初始化后List不为空,即使将属性改为非const并触发ListChanged信号,文本仍未显示。在ListView的Component.onCompleted中打印_Controller._List,输出为qml: QVariant(QList<Subject>, )。
以下是我的代码:
自定义Subject类
class Subject : public QObject { Q_OBJECT public: int First; int Second; explicit Subject(int fFirst = 0, int fSecond = 0, QObject *parent = nullptr) { this->First = fFirst; this->Second = fSecond; emit FirstChanged(); emit SecondChanged(); } Subject::Subject(const Subject &Copy) { this->First = Copy.First; this->Second = Copy.Second; emit FirstChanged(); emit SecondChanged(); } void Subject::operator=(const Subject &Right) { this->First = Right.First; this->Second = Right.Second; } private: Q_PROPERTY(int _First READ getFirst WRITE setFirst NOTIFY FirstChanged FINAL) Q_PROPERTY(int _Second READ getSecond WRITE setSecond NOTIFY SecondChanged FINAL) };
Controller类
class Controller : public QObject { Q_OBJECT public: explicit Controller(QObject *parent = nullptr) { this->List.push_back(Subject(1, 0)); this->List.push_back(Subject(2, 0)); } QVector<Subject> List; QVector<Subject> getList() const; void setList(const QVector<Subject> &newList); Q_INVOKABLE void printAll(); private: Q_PROPERTY(QVector<Subject> _List READ getList CONSTANT) };
QML代码
Controller { id: _Controller Component.onCompleted: { _Controller.printAll() } } ListView { anchors.fill: parent model: _Controller._List Component.onCompleted: { for (let i = 0; i < 2; i++) { console.log(_Controller._List) } } delegate: Text { id: _delegated text: qsTr(modelData._First) font.bold: true color: "black" font.pointSize: 24 } }
解决方案
你的代码存在几个关键问题,导致QML无法正确识别和遍历QVector中的数据:
1. 未注册自定义类型到QML
QML无法直接识别未注册的C++自定义类,需在main函数中通过qmlRegisterType注册类型:
#include <QQmlApplicationEngine> #include "subject.h" #include "controller.h" int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); qmlRegisterType<Subject>("com.yourcompany.models", 1, 0, "Subject"); qmlRegisterType<Controller>("com.yourcompany.controllers", 1, 0, "Controller"); QQmlApplicationEngine engine; const QUrl url(u"qrc:/main.qml"_qs); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url); return app.exec(); }
同时在QML文件开头导入注册的模块:
import com.yourcompany.models 1.0 import com.yourcompany.controllers 1.0
2. QVector存储QObject派生类的方式错误
QObject派生类不能直接以值类型存储在QVector中(会引发对象所有权和拷贝冲突),必须存储指针类型QVector<Subject*>,且要删除Subject类中的拷贝构造函数和赋值运算符(QObject默认禁用拷贝)。
修改Controller类:
class Controller : public QObject { Q_OBJECT public: explicit Controller(QObject *parent = nullptr) { // 指定父对象避免内存泄漏 List.push_back(new Subject(1, 0, this)); List.push_back(new Subject(2, 0, this)); } QVector<Subject*> List; QVector<Subject*> getList() const { return List; } void setList(const QVector<Subject*> &newList); Q_INVOKABLE void printAll(); private: Q_PROPERTY(QVector<Subject*> _List READ getList CONSTANT) };
3. Q_PROPERTY的定义错误
Subject类中的Q_PROPERTY权限错误,且未实现对应的读写方法,需修正为:
class Subject : public QObject { Q_OBJECT Q_PROPERTY(int first READ first WRITE setFirst NOTIFY firstChanged FINAL) Q_PROPERTY(int second READ second WRITE setSecond NOTIFY secondChanged FINAL) public: explicit Subject(int fFirst = 0, int fSecond = 0, QObject *parent = nullptr) : QObject(parent), m_first(fFirst), m_second(fSecond) { } int first() const { return m_first; } void setFirst(int first) { if (m_first != first) { m_first = first; emit firstChanged(); } } int second() const { return m_second; } void setSecond(int second) { if (m_second != second) { m_second = second; emit secondChanged(); } } signals: void firstChanged(); void secondChanged(); private: int m_first; int m_second; };
4. QML中模型数据的访问修正
修改QML的delegate,使用正确的属性名访问:
delegate: Text { text: qsTr(modelData.first.toString()) font.bold: true color: "black" font.pointSize: 24 }
可选优化:使用QAbstractListModel
如果需要支持模型数据的动态增删改,推荐继承QAbstractListModel实现自定义模型,这更符合Qt Model-View架构,能自动通知QML数据变化。
内容的提问来源于stack exchange,提问作者VoiceShifter
相关产品推荐
相关产品推荐

