簡體   English   中英

如何為QML創建通用ListModel

[英]How to create a Generic ListModel for QML

我的應用程序包含許多列表,這些列表是通過使用QAbstractListModel派生的模型類在QML-ListViews中顯示的。 始終相同,但Item-Type有所不同。 這就是為什么我想知道如何為這種方法構建一個類模板。

我發現,不可能在類模板中使用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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM