如何为QML创建通用ListModel
How to create a Generic ListModel for QML
我的应用程序由许多列表组成,我使用QAbstractListModel派生的模型类在QML ListViews中显示这些列表。它总是一样的,只是项目类型不同。这就是为什么我想知道如何为这种方法构建一个类模板。
我发现,在类模板中使用Q_OBJECT-Macro是不可能的。这就是为什么我的GenericListModel由两部分组成。
1.GenericListModelData
第一部分是模型本身,它从QAbstractListModel派生并实现基本函数data()、rowCount()和roleNames()。
2.GenericListModel
第二部分是类模板,它被用作包装器,以提供类似于QListView的函数。
如果你有任何建议或问题,请告诉我。如果能改进这个解决方案,那就太好了。
我在这里上传了完整的源代码:https://github.com/sebabebibobu/QGenericListModel/
1.GenericListModelData
QVariant GenericListModelData::data(const QModelIndex &index, int role) const
{
QObject *item = m_itemList.at(index.row());
return item->property(item->metaObject()->property(role).name());
}
/*
* Returns the number of items attached to the list.
*/
int GenericListModelData::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_itemList.size();
}
/*
* Generates a hash out of QMetaObject property-index and property-name.
*/
QHash<int, QByteArray> GenericListModelData::roleNames() const
{
QHash<int, QByteArray> roles;
if (!m_itemList.isEmpty()) {
for(int i = 0; i < m_itemList.at(0)->metaObject()->propertyCount(); i++) {
roles[i] = m_itemList.at(0)->metaObject()->property(i).name();
}
}
return roles;
}
/*
* Append Item to List.
*/
void GenericListModelData::appendItem(QObject *item)
{
/* map the notify()-signal-index with the property-index when the first item get's inserted */
if (m_itemList.isEmpty()) {
for(int i = 0; i < item->metaObject()->propertyCount(); i++) {
m_propertySignalIndexHash.insert(item->metaObject()->property(i).notifySignalIndex(), i);
}
}
/* connect each notify()-signals to the onDataChanged()-slot which call's the dataChanged()-signal */
for(int i = 0; i < item->metaObject()->propertyCount(); i++) {
connect(item, "2" + item->metaObject()->property(i).notifySignal().methodSignature(), this, SLOT(onDataChanged()));
}
/* finally append the item the list */
beginInsertRows(QModelIndex(), rowCount(), rowCount());
m_itemList.append(item);
endInsertRows();
}
/*
* Helper-Slot that emit's the dataChanged()-signal of QAbstractListModel.
*/
void GenericListModelData::onDataChanged()
{
QModelIndex index = createIndex(m_itemList.indexOf(sender()),0);
QVector<int> roles;
roles.append(m_propertySignalIndexHash.value(senderSignalIndex()));
emit dataChanged(index, index, roles);
}
2.GenericListModel
template <typename T>
class GenericListModel : public GenericListModelData
{
public:
explicit GenericListModel(QObject *parent) : GenericListModelData(parent) {
}
void append(T *item) {
appendItem(item);
}
T *at(int i) {
return qobject_cast<T *>(m_itemList.at(i));
}
};
更新01.05.2016
GrecKo在评论中表示,像我这样的项目已经存在。这就是为什么我决定在这里分享这个项目的链接:
http://gitlab.unique-conception.org/qt-qml-tricks/qt-qml-models
相关文章:
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 使用std::multimap迭代器创建std::list
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 使用CMake创建QML插件
- 如何在c++中为模板函数实例创建快捷方式
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- OpenCV EqualizeHist()从彩色图像创建黑白图像
- 试图在visual studio上用C++创建一个桌面应用程序
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 如何在C++20中创建模板别名的推导指南
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 如何创建一个空的全局类并在启动时实例化它
- 无法创建抽象类的实例
- 链接到自行创建的dll失败
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 如何在C++类内存结构中创建"spacer"?
- 终端不会为C++文件创建.exe文件吗
- 如何为QML创建通用ListModel