为什么我无法从 QML 读取公开的C++数据?
Why can't I read exposed C++ datas from QML?
我创建了这个类,将其用作数据容器。我从json中读取了一些数据(在c++中),并填充了一个GUIArea列表,该列表存储在dataHandler的m_guiAreas列表中。在QML的某个时刻,我向数据处理程序请求一系列selectedAreas。数据处理程序填充QList m_selectedGuiAres并发出selectedAreasChanged()信号。现在,我希望使用一个矩形网格来填充选定的数据,但我什么也没看到。在C++级别,当selectedAreasChanged()发出时,m_selectedGuiAres结果填充了正确的数据,但在QML级别,它似乎是空的,或者可能数据没有正确读取。
以下是我用作包装器的类,用于将数据带到QML级别:
class GUIArea : public QObject
{
Q_OBJECT
Q_PROPERTY(QString id READ id )
Q_PROPERTY(QString configurations READ configurations )
...
public:
explicit GUIArea(QObject *parent = nullptr): QObject (parent) {}
QString id() {return m_id;}
void id(QString newId) {m_id = newId;}
QString configurations() {return m_configuration; }
void configurations(QString newConfiguration) {m_configuration = newConfiguration;}
...
private:
QString m_id;
QString m_configuration;
};
下面是dataHandler类,我在其中声明从Json读取的数据列表,并将其从Qlist转换为QQmlPropertyList(我在一些向QML公开c++属性的QML指南中看到了这一点)。该方法初始化datas读取存储在m_GUIAreas中的数据,然后选择一个发送到m_selectedGUIAs中的QML,最后发出信号selectedGUAsChanged()。
class dataHandler : public QObject
{
Q_OBJECT
Q_PROPERTY(QQmlListProperty<GUIArea> selectedGuiAreas READ selectedGuiAreas NOTIFY selectedAreasChanged)
public:
explicit dataHandler(QObject *parent = nullptr);
static dataHandler* instance();
QQmlListProperty<GUIArea> selectedGuiAreas();
...
public slots:
void initializeDatas(const json& blocksList);
...
signals:
...
void selectedAreasChanged();
...
private:
...
QList<GUIArea *> m_guiAreas;
QList<GUIArea *> m_selectedGuiAreas;
};
在主文件中,dataHandler被声明为一个属性:这是代码:
QQuickView view;
...
view.engine()->rootContext()->setContextProperty("dataHandler", dataHandler::instance());
...
view.show();
下面是我想在QML中看到的页面的一部分。AreaButton是文本中的矩形,也是属性文本的别名。
Grid {
id: areasButtonsGrid
columns: 4
anchors.fill: parent
Repeater {
model: dataHandler.selectedGuiAreas
delegate:
AreaButton {
text: qsTr(model.modelData.programName)
}
}
}
由于代码不完整,因此无法对其进行分析,因此我只提供一个工作代码,以便您可以分析问题所在:
main.cpp
#include <QGuiApplication>
#include <QQmlContext>
#include <QQuickView>
#include <QTimer>
class GUIArea : public QObject
{
Q_OBJECT
Q_PROPERTY(QString id READ id CONSTANT)
Q_PROPERTY(QString configurations READ configurations CONSTANT)
public:
GUIArea(const QString & id="", const QString & configurations="", QObject *parent=nullptr):
QObject(parent), m_id(id), m_configurations(configurations)
{}
QString id() const{return m_id;}
QString configurations() const{return m_configurations;}
void setId(const QString &id){
m_id = id;
}
void setConfigurations(const QString &configurations){
m_configurations = configurations;
}
private:
QString m_id;
QString m_configurations;
};
class DataHandler: public QObject
{
Q_OBJECT
Q_PROPERTY(QQmlListProperty<GUIArea> selectedGuiAreas READ selectedGuiAreas NOTIFY selectedAreasChanged)
using QObject::QObject;
public:
static DataHandler& instance(){
static DataHandler handler;
return handler;
}
QQmlListProperty<GUIArea> selectedGuiAreas(){
return QQmlListProperty<GUIArea>(this, m_selectedGuiAreas);
}
void append(GUIArea *area){
if(area){
m_selectedGuiAreas << area;
emit selectedAreasChanged();
}
}
signals:
void selectedAreasChanged();
private:
QList<GUIArea *> m_selectedGuiAreas;
};
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
qmlRegisterType<GUIArea>();
QQuickView view;
view.rootContext()->setContextProperty("dataHandler", &DataHandler::instance());
view.setSource(QUrl(QStringLiteral("qrc:/main.qml")));
view.show();
QTimer timer;
static int counter =0;
QObject::connect(&timer, &QTimer::timeout, [](){
GUIArea *area = new GUIArea(QString::number(counter),
QString("configuratio-%1").arg(counter),
&DataHandler::instance());
DataHandler::instance().append(area);
counter++;
});
timer.start(1000);
return app.exec();
}
#include "main.moc"
main.qml
import QtQuick 2.12
Grid {
id: areasButtonsGrid
columns: 5
width: 640
height: 480
spacing: 20
Repeater {
model: dataHandler.selectedGuiAreas
delegate:
Rectangle{
width: 100
height: 100
color: "blue"
Text {
anchors.fill: parent
text: qsTr(model.modelData.configurations)
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}
}
}
}
相关文章:
- 防止主数据类型C++的隐式转换
- 用于访问容器<T>数据成员的正确 API
- 嵌套在类中时无法设置成员数据
- 使用流处理接收到的数据
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 在cuda线程之间共享大量常量数据
- C++将文本文件中的数据读取到结构数组中
- 如何在C++中序列化结构数据
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 在c代码之间共享数据的最佳方式
- 链表,反向函数,数据结构
- 数据成员SFINAE的C++17测试:gcc vs clang
- C++浮点数据类型和字符串数据类型无法子到模板函数中
- 如何对点云数据进行排序
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- 尝试通过OCI例程从Oracle获取blob数据,但出现错误:ORA-01008:并非所有变量都绑定
- Cuda C++:设备上的Malloc类,并用来自主机的数据填充它
- 在运行时处理类型擦除的数据-如何不重新发明轮子