c++ - 在运行时将带有类实例的列表从 c++ 导入到 qml 的建议
问题描述
我有一个 QList,其中每个元素都是 C++ 类的一个实例。这些实例包含信息,并基于我想在 QML 中创建和移动矩形。包含的信息是 x 位置(除其他外),我想为 QList 中的每个元素创建/移动一个矩形。QList 在运行时定期更新,这意味着可以添加、删除某些元素或编辑 x 位置。
我编写了一个小示例来了解如何完成 c++ 和 QML 之间的桥梁,但我认为我的代码只能作为初始化工作一次,如果我在运行时更新 QList 则不会。我是否在正确的轨道上,如果没有,我必须改变什么?是否有必要使用 QAbstractListModel 就像Timmmmm在这个问题的答案中所建议的那样?
这是我的代码:
class.h:
#ifndef CLASS_H
#define CLASS_H
#include <QQuickItem>
class RectangelClass : public QObject
{
private:
Q_OBJECT
Q_PROPERTY(int xPos READ xPos WRITE setXPos NOTIFY xPosChanged)
int m_xPos;
public:
RectangelClass () {}
int xPos() const { return m_xPos; }
public slots:
void setXPos(int arg)
{
if (m_xPos == arg)
return;
m_xPos = arg;
emit xPosChanged(arg);
}
signals:
void xPosChanged(int arg);
};
class RectangelClassManager : public QObject
{
private:
Q_OBJECT
Q_PROPERTY(QList <QObject*> rectangelClassList READ rectangelClassList WRITE setRectangelClassList NOTIFY rectangelClassListChanged)
QList <QObject*> m_rectangelClassList;
public:
RectangelClassManager ()
{
QList <QObject*> localObjList;
for (int i = 0; i < 5; i++)
{
RectangelClass *localObj = new RectangelClass();
localObj->setXPos (i*100);
localObjList.push_back(localObj);
}
setRectangelClassList (localObjList);
}
QList <QObject*> rectangelClassList () const { return m_rectangelClassList; }
public slots:
void setRectangelClassList (QList <QObject*> arg)
{
if (m_rectangelClassList == arg)
return;
m_rectangelClassList = arg;
emit rectangelClassListChanged(arg);
}
signals:
void rectangelClassListChanged (QList <QObject*> arg);
};
#endif // CLASS_H
主.cpp:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "class.h"
#include <iostream>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
qmlRegisterType<RectangelClass>("cppclasses", 1, 0, "RectangelClass");
qmlRegisterType<RectangelClassManager>("cppclasses", 1, 0, "RectangelClassManager");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
main.qml:
import QtQuick 2.4
import QtQuick.Window 2.2
import cppclasses 1.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
RectangelClassManager{
id: rectangelClassManager
}
Rectangle{
id: rect0
x: rectangelClassManager.rectangelClassList[0].xPos
y: 100
width: 80
height: 80
color:"yellow"
Text {
id: textid0
anchors.centerIn: parent
text: "X-Position: " + rectangelClassManager.rectangelClassList[0].xPos
}
}
Rectangle{
id: rect1
x: rectangelClassManager.rectangelClassList[1].xPos
y: 100
width: 80
height: 80
color:"yellow"
Text {
id: textid1
anchors.centerIn: parent
text: "X-Position: " + rectangelClassManager.rectangelClassList[1].xPos
}
}
Rectangle{
id: rect2
x: rectangelClassManager.rectangelClassList[2].xPos
y: 100
width: 80
height: 80
color:"yellow"
Text {
id: textid2
anchors.centerIn: parent
text: "X-Position: " + rectangelClassManager.rectangelClassList[2].xPos
}
}
Rectangle{
id: rect3
x: rectangelClassManager.rectangelClassList[3].xPos
y: 100
width: 80
height: 80
color:"yellow"
Text {
id: textid3
anchors.centerIn: parent
text: "X-Position: " + rectangelClassManager.rectangelClassList[3].xPos
}
}
Rectangle{
id: rect4
x: rectangelClassManager.rectangelClassList[4].xPos
y: 100
width: 80
height: 80
color:"yellow"
Text {
id: textid4
anchors.centerIn: parent
text: "X-Position: " + rectangelClassManager.rectangelClassList[4].xPos
}
}
}
编辑以使我的问题更清楚:
是否可以在 C++ 中在运行时更新 QList,是否会在 QML 中更新,如果没有,我该如何实现。
解决方案
是的,QList
可以通过发出rectangelClassListChanged()
信号在运行时更新属性。但是,这可能非常低效,因为整个列表都被重新解析了。因此,根据您QList
更改的频率,您最好将其更改为QAbstractListModel
.
此外,您可以将代码更改为使用 a Repeater
,这会伤害我的程序员的眼睛 ;-) 这实际上可能是不更新运行时的原因。
import QtQuick 2.4
import QtQuick.Window 2.2
import cppclasses 1.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
RectangelClassManager{
id: rectangelClassManager
}
Repeater {
model: rectangelClassManager.rectangelClassList
delegate: Rectangle {
x: modelData.xPos
y: 100
width: 80
height: 80
color:"yellow"
Text {
id: textid0
anchors.centerIn: parent
text: "X-Position: " + modelData.xPos
}
}
}
}
推荐阅读
- c# - WebService to Stored Procedure with XML response to WebService with DS.GETXML change < to <
- javascript - 有什么方法可以不使用 Webpack/React 打包?
- python - 无法导入通过 conda 离线安装的 python 包
- vue.js - 无法让地图与 highcharts-vue 一起使用
- import - 如何将格式化的 .csv 数据导入 SAS?
- prolog - 如何在第一个列表中保留在第二个列表中出现偶数的元素?(序言)
- php - 如何在来自 HTML 的 JSON AJAX 请求中添加滑块
- java - 在画廊 kotlin 上选择照片
- android - 设备进入某个位置时没有触发地理围栏
- instagram-api - 如何在可交付代码中验证 Instagram 应用程序?