【问题标题】:How to use QAbstractItemModel for ComboBox如何为 ComboBox 使用 QAbstractItemModel
【发布时间】:2021-12-22 09:39:09
【问题描述】:

我已将 QAbstractItemModel 实现为 C++ 类,并尝试将其用作 QComboBox 的模型。该模型存储 QString 的 QList,它们是项目应用程序 INI 文件的名称。我可以将列表打印到控制台中,而且我肯定得到了正确的文件列表。但是我收到一个错误无法将 [undefined] 分配给 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

【问题讨论】:

    标签: c++ qt qml qcombobox qabstractitemmodel


    【解决方案1】:

    模型不需要从 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
                }
            }
        }
    }
    

    【讨论】:

    • 哦,非常感谢您的帮助。现在完全可以用了!
    猜你喜欢
    • 2012-05-02
    • 2015-11-17
    • 1970-01-01
    • 2017-06-07
    • 2014-03-28
    • 2021-07-18
    • 1970-01-01
    • 1970-01-01
    • 2015-12-02
    相关资源
    最近更新 更多