簡體   English   中英

如何將 QAbstractItemModel 用於 ComboBox

[英]How to use QAbstractItemModel for ComboBox

我已經將 QAbstractItemModel 實現為一個 C++ 類,我正在嘗試將它用作 QComboBox 的模型。 該模型存儲 QStrings 的 QList,它們是項目應用程序 INI 文件的名稱。 我可以將列表打印到控制台中,而且我肯定會得到正確的文件列表。 但是我收到一個錯誤Unable to assign [undefined] to QString 你能幫我嗎,我做錯了什么?

LcuModel.cpp

#include "LcuModel.h"
#include "logging/LoggingQtCategories.h"

#include <QCoreApplication>
#include <QSettings>
#include <QFileInfo>
#include <QDir>

LcuModel::LcuModel(QObject *parent)
    : QAbstractItemModel(parent)
{
    QSettings settings;
    QFileInfo fileInfo(settings.fileName());
    QDir directory(fileInfo.absolutePath());
    iniFiles_ = directory.entryList({"*.ini"},QDir::Files);
    if (iniFiles_.empty())
    {
        qCWarning(lcLcu) << "No ini files were found.";
    }
    qCInfo(lcLcu) << iniFiles_; //this prints out all the files to console, so the list is certainly not empty
}

QModelIndex LcuModel::index(int row, int column, const QModelIndex &parent) const
{
    Q_UNUSED(row)
    Q_UNUSED(column)
    Q_UNUSED(parent)
    return QModelIndex();
}

QModelIndex LcuModel::parent(const QModelIndex &index) const
{
    Q_UNUSED(index)
    return QModelIndex();
}

int LcuModel::rowCount(const QModelIndex & parent) const {
    Q_UNUSED(parent)
    return iniFiles_.count();
 }

int LcuModel::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent)
    return 1;
}

QVariant LcuModel::data(const QModelIndex & index, int role) const
{
    Q_UNUSED(role);
    int row = index.row();
    qCInfo(lcLcu) << QString::number(row) << " ";
    if (row < 0 || row >= iniFiles_.count()) {
        return QVariant();
    }

    return QVariant(iniFiles_.at( index.row() ));
}
QHash<int, QByteArray> LcuModel::roleNames() const
{
    QHash<int, QByteArray> names;
    names[textRole] = "fileName";
    return names;
}

LcuModel.h

#ifndef LCUMODEL_H
#define LCUMODEL_H

#include <QAbstractItemModel>

class LcuModel : public QAbstractItemModel
{
    Q_OBJECT

public:
    explicit LcuModel(QObject *parent = nullptr);

    enum {
        textRole
    };

    QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
    QModelIndex parent(const QModelIndex &index) const override;

    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    int columnCount(const QModelIndex &parent = QModelIndex()) const override;

    QVariant data(const QModelIndex &index, int role) const override;

protected:
    virtual QHash<int, QByteArray> roleNames() const override;

private:
    QList<QString> iniFiles_;
};

#endif // LCUMODEL_H

LcuMain.qml

import QtQuick 2.12
import QtQuick.Controls 2.12
import project.lcu 1.0

Item {
    id: lcuMain

    LcuModel{
        id:lcuModel
    }

    Component.onCompleted: {
        console.info("Completed "+ comboBox.count + "items")
    } //this gives me right number of items from the list
    Column{
        ComboBox{
            id: comboBox
            model: lcuModel
            delegate: ItemDelegate
            {
                contentItem: Text {
                    text: fileName
                }
            }
            onActivated: console.info(comboBox.currentText + comboBox.currentIndex) //it prints out an empty string
        }
    }
}

控制台輸出

18:02:25.543 [ info  ] project.lcu: LcuModel::LcuModel - ("first.ini", "second.ini", "third.ini", "fourth.ini", "fifth.ini", "sixth.ini", "seventh.ini", "eight.ini", "nineth.ini")
18:02:25.616 [warning] unknown - ComboBox.qml:47:5: QML Connections: Cannot assign to non-existent property "onCountChanged"
18:02:25.675 [ info  ] qml: onCompleted - 9
18:02:25.678 [warning] unknown - qrc:/LcuMain.qml:46:25: Unable to assign [undefined] to QString

模型不需要從 QAbstractItemModel 繼承,QAbstractListModel 就足夠了,因此您不必實現多個方法。 另一方面,您必須通過 textRole 建立要顯示的角色,並且必須在委托中使用 modelData:

#ifndef LCUMODEL_H
#define LCUMODEL_H

#include <QAbstractListModel>

class LcuModel : public QAbstractListModel
{
    Q_OBJECT

public:
    enum {
        textRole = Qt::UserRole
    };
    explicit LcuModel(QObject *parent = nullptr);
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    QHash<int, QByteArray> roleNames() const override;
private:
    QStringList iniFiles_;
};

#endif // LCUMODEL_H
#include "lcumodel.h"

#include <QDir>
#include <QFileInfo>
#include <QSettings>


LcuModel::LcuModel(QObject *parent)
    : QAbstractListModel(parent)
{

    QSettings settings;
    QFileInfo fileInfo(settings.fileName());
    QDir directory(fileInfo.absolutePath());
    iniFiles_ = directory.entryList({"*.ini"}, QDir::Files);
}

int LcuModel::rowCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;
    return iniFiles_.length();
}

QVariant LcuModel::data(const QModelIndex &index, int role) const
{
    if(!checkIndex(index)){
        return QVariant();
    }
    if(role == textRole){
        return iniFiles_.at(index.row());
    }
    return QVariant();
}

QHash<int, QByteArray> LcuModel::roleNames() const
{
    QHash<int, QByteArray> names;
    names[textRole] = "fileName";
    return names;
}
import QtQuick 2.12
import QtQuick.Controls 2.12
import project.lcu 1.0

Item{
    id: lcuMain

    LcuModel{
        id:lcuModel
    }

    Column{
        ComboBox{
            id: comboBox
            model: lcuModel
            textRole: "fileName"
            delegate: ItemDelegate{
                text: modelData
                width: parent.width
            }
        }
    }
}

暫無
暫無

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

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