gpt4 book ai didi

c++ - 从 QML 访问 C++ 模型

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:03:07 25 4
gpt4 key购买 nike

我创建了一个最小的工作示例。我希望这是可以理解的。我的问题是我无法为顶级项目创建模型以便进一步访问项目。这是类对象体系结构的样子:

CTop
x times CMiddle
y times CBottom

这是一个树结构。这是代码:

CBottom.h:

#ifndef CBOTTOM_H
#define CBOTTOM_H

#include <QObject>
#include <QtQml>

class CBottom : public QObject
{
Q_OBJECT

Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)

public:

CBottom(QObject *parent = nullptr) : QObject(parent)
{

}

CBottom(const QString& name, QObject *parent = nullptr) : QObject(parent)
{
qmlRegisterType<CBottom>("Bottom", 1, 0, "Bottom");
m_name = name;
}

QString name()
{
return m_name;
}

void setName(const QString& name)
{
if (name != m_name)
{
m_name = name;
emit nameChanged();
}
}

signals:

void nameChanged();

private:

QString m_name;
};

#endif // CBOTTOM_H

CMiddle.h:

#ifndef CMIDDLE_H
#define CMIDDLE_H

#include <QObject>
#include <QtQml>
#include <QVector>

#include "cbottom.h"

class CMiddle : public QObject
{
Q_OBJECT

Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)

public:

CMiddle(QObject *parent = nullptr) : QObject(parent)
{

}

CMiddle(const QString& name, const QStringList& bottoms, QObject *parent = nullptr) : QObject(parent)
{
qmlRegisterType<CMiddle>("Middle", 1, 0, "Middle");
m_name = name;

foreach (auto bottom, bottoms)
{
m_bottoms.append(new CBottom(bottom));
}
}

QString name()
{
return m_name;
}

void setName(const QString& name)
{
if (name != m_name)
{
m_name = name;
emit nameChanged();
}
}

signals:

void nameChanged();

private:

QString m_name;
QVector<CBottom*> m_bottoms;
};

#endif // CMIDDLE_H

CTop.h:

#ifndef CTOP_H
#define CTOP_H

#include <QObject>
#include <QtQml>

#include "cmiddle.h"

class CTop : public QObject
{
Q_OBJECT

public:

CTop(QObject *parent = nullptr) : QObject(parent)
{

}

CTop(const QStringList& middles, QObject *parent = nullptr) : QObject(parent)
{
qmlRegisterType<CTop>("Top", 1, 0, "Top");
int i = 0;

foreach (auto middle, middles)
{
QStringList bottoms;
bottoms.append("A" + QString(i));
bottoms.append("B" + QString(i));
bottoms.append("C" + QString(i));
i++;

m_middles.append(new CMiddle(middle, bottoms));
}
}

Q_INVOKABLE QVector<CMiddle*>& middles()
{
return m_middles;
}

Q_INVOKABLE CMiddle* middle(const int index)
{
return m_middles[index];
}

private:

QVector<CMiddle*> m_middles;

};

#endif // CTOP_H

主.c:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QString>
#include <QVector>
#include <QStringList>
#include <QVariant>
#include <QQmlContext>

#include "ctop.h"


int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

QGuiApplication app(argc, argv);

QStringList middles;
middles.append("FirstMiddle");
middles.append("SecondMiddle");

CTop* top = new CTop(middles);

QQmlApplicationEngine engine;
QQmlContext *ctxt = engine.rootContext();
ctxt->setContextProperty("theTop", QVariant::fromValue(top));

engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;

return app.exec();
}

主.qml:

import QtQuick 2.9
import QtQuick.Window 2.2

import Top 1.0

Window
{
width: 600
height: 400
visible: true

Repeater
{
model: theTop.middles();
delegate: txtComp;
}

Component
{
id: txtComp;

Text
{
text: name;
}
}

}

问题是:为什么 CMiddle 对象之一的名称没有显示在 QML 代码中?我想从导出到 QML CTop 组件中获取 CMiddle 组件(充当模型)。如果这段代码有效,我会更进一步,制作另一个模型来访问每个 CMiddle 对象中的 CBottom 对象。

例如,我注意到这段 QML 代码有效:

import QtQuick 2.9
import QtQuick.Window 2.2

import Top 1.0

Window
{
width: 600
height: 400
visible: true

Repeater
{
model: theTop;
delegate: txtComp;
}

Component
{
id: txtComp;

Text
{
text: middle(0).name;
}
}

}

enter image description here

它没有多大意义,但表明 CTop 组件已正确暴露给 QML 部分。

为什么CMiddle指针的输出Qvector不能作为QML部分的模型?

最佳答案

QML 不知道QList<CMiddle *> , 相反你应该使用 QList<QObject *> :

CTop.h

// ...
Q_INVOKABLE QList<QObject*> middles(){
QList<QObject*> objects;
for(CMiddle *m : qAsConst(m_middles)){
objects << m;
}
return objects;
}
// ...

还有一个错误是 top 不一定是一个指针,你可以不使用 QVariant::fromValue() 来传递它。因为它是 QObject :

main.cpp

// ...
CTop top(middles);
QQmlApplicationEngine engine;
QQmlContext *ctxt = engine.rootContext();
ctxt->setContextProperty("theTop", &top);

同样在 Repeater 中使用 modelData 获取模型的项目:

ma​​in.qml

//...
Component{
id: txtComp;
Text{
text: modelData.name
}
}
//...

完整工程可见here

关于c++ - 从 QML 访问 C++ 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55857689/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com