- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个非常简单的类,它有两个属性;键和值:
KeyValue.h:
class KeyValue : public QObject
{
Q_OBJECT
Q_PROPERTY(QString key READ getKey WRITE setKey NOTIFY keyChanged)
Q_PROPERTY(QString value READ getValue WRITE setValue NOTIFY valueChanged)
public:
KeyValue(const QString& key, const QString& value, QObject* parent = 0);
signals:
void keyChanged();
void valueChanged();
private:
QString _key;
QString _value;
QString getKey() const;
QString getValue() const;
void setKey(const QString& key);
void setValue(const QString& value);
};
Q_DECLARE_METATYPE(KeyValue)
在另一个类中,我想要一个包含 KeyValue 对象列表的属性,因此我可以将此列表用作 QML 中的模型。
Controller.h
class Controller : public QObject
{
Q_OBJECT
Q_PROPERTY(QList<KeyValue*> items READ getItems NOTIFY itemsChanged)
public:
explicit Controller(QObject* parent = 0);
signals:
void itemsChanged();
private:
QList<KeyValue*> getItems() const;
};
我希望能够通过以下方式在 QML 中使用它:
import QtQuick 2.7
import customqml 1.0
Item{
Controller{
id: controller
}
Repeater{
model: controller.items
Text{
text: modelData.key + ": " + modelData.value
}
}
}
这两个类都在我的 main.cpp 文件中注册:
qmlRegisterType<KeyValue>("customqml", 1, 0, "KeyValue");
qmlRegisterType<Controller>("customqml", 1, 0, "Controller");
上面的代码不起作用,因为我显然不能直接将 QList 公开给 QML。我尝试过使用 QAbstractItemModel 和 QQmlListProperty,但我无法让它工作。谁能指出我正确的方向?
我的主要问题是 Controller 类中 items 属性的类型和 getItems 方法的返回值。
如果有任何不同,我正在使用 Qt 5.9。
最佳答案
注意:
除异常(exception)情况外,getter 和 setter 通常是公共(public)的,因此将其移至公共(public)部分
继承自 QObject 的类不需要 QMetaType,因为当您要传输该类的数据时,会使用指针。
并非所有数据类型都通过 Q_PROPERTY 被 QML 支持,因此一个可能的解决方案是通过已知类导出,例如
QList<QObject *>
:class Controller : public QObject
{
Q_OBJECT
Q_PROPERTY(QList<QObject *> items READ getItems NOTIFY itemsChanged)
public:
explicit Controller(QObject *parent = nullptr);
QList<QObject *> getItems() const;
signals:
void itemsChanged();
private:
QList<KeyValue *>key_values_list;
};
...
QList<QObject *> Controller::getItems() const
{
QObjectList l;
for(auto e: key_values_list)
l << e;
return l;
}
QVariantList
:class Controller : public QObject
{
Q_OBJECT
Q_PROPERTY(QVariantList items READ getItems NOTIFY itemsChanged)
public:
explicit Controller(QObject *parent = nullptr);
QVariantList getItems() const;
signals:
void itemsChanged();
private:
QList<KeyValue *>key_values_list;
};
...
QVariantList Controller::getItems() const
{
QVariantList l;
for(auto e: key_values_list)
l.append(QVariant::fromValue(e));
return l;
}
其他选项是实现一个模型,下面的例子只展示了一个只读模型:
键值模型.h
#ifndef KEYVALUEMODEL_H
#define KEYVALUEMODEL_H
#include "keyvalue.h"
#include <QAbstractListModel>
class KeyValueModel : public QAbstractListModel
{
Q_OBJECT
public:
explicit KeyValueModel(QObject *parent = nullptr)
: QAbstractListModel(parent)
{
key_values_list = {new KeyValue{"k", "v"}, new KeyValue{"k2", "v2"}};
}
int rowCount(const QModelIndex &parent = QModelIndex()) const override
{
if (parent.isValid())
return 0;
return key_values_list.length();
}
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
{
if (!index.isValid())
return QVariant();
if(index.row() >= 0 && index.row() < rowCount())
return QVariant::fromValue(key_values_list[index.row()]);
return QVariant();
}
private:
QList<KeyValue* >key_values_list;
};
#endif // KEYVALUEMODEL_H
class Controller : public QObject
{
Q_OBJECT
Q_PROPERTY(KeyValueModel* items READ getItems NOTIFY itemsChanged)
public:
explicit Controller(QObject *parent = nullptr);
KeyValueModel* getItems() const;
signals:
void itemsChanged();
private:
KeyValueModel *model;
};
...
Text{
text: display.key + ": " + display.value
}
...
您可以用类似的方式实现 QQmlListProperty,在文档中有很多示例。
关于c++ - 如何使用 Q_PROPERTY 公开自定义对象列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52834863/
在此: Q_PROPERTY(QString datastring READ showdata() NOTIFY datastringChanged) 是datastringChanged用于在 QM
我正在使用 Q_PROPERTY s 在我的项目中,我试图找出向这些属性添加一些属性的最佳方法( like min and max value )。 看起来没有任何地方可以在属性本身上存储这些属性..
我的目标是实现更多的代码重用,同时保持冗长。 考虑以下示例代码: // qdot@defixio /tmp/test4 $ cat test.h #include class Foo : publi
我正在将 Q_PROPERTY 与 QML 一起使用。我的代码是: using namespace std; typedef QString lyricsDownloaderString; // th
考虑这些类: Class A : public QObject { ... Q_PROPERTY(int value READ value WRITE setValue NOTIFY
考虑这些类: Class A : public QObject { ... Q_PROPERTY(int value READ value WRITE setValue NOTIFY
我正在尝试将抽象类的实例用作我的一个扩展 QQuickItems 中的属性。我有一个基础类(class),像这样: class VizFactory : public QQuickItem {
我有一个 Configuration,其中包含一些关于文件位置的基本信息,例如下载、安装、图片、音乐、文档等位置。这些目前使用 Q_PROPERTY 暴露给 QML。它们都有自己的访问器: Q_PRO
我是 QT 属性系统的新手,我想了解为什么如果我以一种方式注册和使用属性,它可以工作,但以另一种方式失败。 我有两个类( A 和 B )都继承自 QObject .类 B包含类 A 的几个实例我想注册
我有两个类,TestA 和 TestB。 TestA 扩展了 QObject。我用一些 Q_PROPERTY 设置了它。 Q_PROPERTY(QString a_string READ getStr
我是 Qt 和 C++ 的新手,但长期使用 Delphi 程序员。 我有一个简单的类,我正在尝试将属性添加到: class Rectangle { Q_PROPERTY(int width R
我有这个属性: Q_PROPERTY(int _a READ a WRITE setA NOTIFY aChanged) 我只知道属性的名称 _a。我想获取方法 setA 的索引。 最佳答案 查看 Q
http://doc.qt.io/qt-5/qtqml-cppintegration-exposecppattributes.html class Message : public QObject {
如何将 Q_PROPERTY 宏放入另一个辅助宏中? #define SimpleAllinOne(member, _type) \ public: \ void Set##member(_t
我习惯用参数编写我的“propertyChanged”signal,这样接收端就不需要调用Q_PROPERTY的READ 功能显式。 我这样做是为了清楚起见,并假设在 QML 数据绑定(bind)情况
TL;DR:如何为与使用 Q_PROPERTY 声明的属性同名的访问器生成 doxygen 文档? Qt 的 property system使得在给定属性上使用 Qt 的元对象系统成为可能: // e
我真的想不通为什么我需要它,一直在阅读: http://doc.qt.io/qt-4.8/properties.html#requirements-for-declaring-properties 还
众所周知,继承的信号不能用作Q_PROPERTY NOTIFYer ( https://bugreports.qt.io/browse/QTBUG-7684 )。作为一种解决方法,我在派生类中使用了一
我有一个非常简单的类,它有两个属性;键和值: KeyValue.h: class KeyValue : public QObject { Q_OBJECT Q_PROPERTY(QString
问题 我正在制作一个使用 Q_OBJECT 和 Q_PROPERTY 从脚本访问一些对象的项目。我有两个问题: 使使用前向声明的类可编写脚本 返回一个属性作为指针 说明 1. 为什么要提前申报? 类
我是一名优秀的程序员,十分优秀!