Это ошибка в Qt Quick ComboBox?

Я использую QAbstractListModel создать собственную модель для ComboBox в Qt Quick. Код в заголовочном файле:

#ifndef JREFINDER_H
#define JREFINDER_H

#include <QObject>
#include <QMap>
#include <QString>
#include <QAbstractListModel>

enum BitSize
{
    BitX86,
    BitX64
};

class JreInformation : public QObject
{
    Q_OBJECT
public:
    ..........
};

class JreFinder : public QAbstractListModel
{
    Q_OBJECT
public:
    enum JreFinderRoles
    {
        JavaPath = Qt::UserRole + 1,
        JavaVerson,
        JavaType,
        Display
    };

    explicit JreFinder(QObject *parent = 0);
    virtual QHash<int, QByteArray> roleNames() const;
    virtual QVariant data(const QModelIndex &index, int role) const;
    virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
    Q_INVOKABLE void refresh();
    Q_INVOKABLE void setIndex(int index);
    Q_INVOKABLE QObject* getJavaInfo();

signals:

public slots:

private:
    int m_index;
    QList<JreInformation*> m_foundJre;
    QHash<int, QByteArray> m_roleNames;
};



#endif // JREFINDER_H

И код в исходном файле:

JreFinder::JreFinder(QObject *parent) : QAbstractListModel(parent)
  ,m_index(0)
{
    m_roleNames.insert(JavaPath, "javaPath");
    m_roleNames.insert(JavaVerson, "javaVersion");
    m_roleNames.insert(JavaType, "javaType");
    m_roleNames.insert(Display, "display");

    QHash<int, QByteArray> defaultRoleNames = QAbstractListModel::roleNames();
    QHashIterator<int, QByteArray> i(defaultRoleNames);
    while (i.hasNext())
    {
        i.next();
        m_roleNames.insert(i.key(), i.value());
    }
}

QHash<int, QByteArray> JreFinder::roleNames() const
{
    return m_roleNames;
}

QVariant JreFinder::data(const QModelIndex &index, int role) const
{
    qDebug()<<"row"<<index.row()<<" role"<<role<<" size"<<m_foundJre.size();
    if(index.row() >= m_foundJre.size() || index.row() < 0)
        return QVariant();

    if(role == JavaPath)
        return m_foundJre[index.row()]->path;
    else if(role == JavaVerson)
        return m_foundJre[index.row()]->version;
    else if(role == JavaType)
        return m_foundJre[index.row()]->type;
    else if(role == Display || role == Qt::DisplayRole) 
    {
        QString d = m_foundJre[index.row()]->display();
        qDebug()<<"display:"<<d;
        return d;
    }

    return QVariant();
}

int JreFinder::rowCount(const QModelIndex &) const
{
    qDebug()<<m_foundJre.size();
    return m_foundJre.size();
}

void JreFinder::refresh()
{
    beginResetModel();

    foreach (JreInformation* info, m_foundJre)
    {
        delete info;
    }
    m_foundJre.clear();

    ReadJreHome(m_foundJre);
    endResetModel();
}

void JreFinder::setIndex(int index)
{
    m_index = index;
}

QObject* JreFinder::getJavaInfo()
{
    if(m_index >= m_foundJre.size() || m_index < 0)
        return NULL;

    return m_foundJre[m_index];
}

И я выставляю его в QML, используя:

JreFinder jreFinder;
jreFinder.refresh();
engine.rootContext()->setContextProperty("jreFinder", &jreFinder);

И создайте ComboBox, используя эту модель:

    ComboBox
    {
        textRole: "display"
        model:jreFinder 
    }

Этот код работает отлично, но посмотрите на эту строку в функции data() исходного файла:

else if(role == Display || role == Qt::DisplayRole)

Я думаю, после того, как я установил textRole из ComboBoxроль отображения должна называться "display", которая является ролью Display в моей пользовательской модели в соответствии с m_roleNames.insert(Display, "display");, Но это не всегда правильно.

Здесь qDebug()<< вывод кода выше:

1
1
ряд 0 роль 260 размер 1
дисплей: "1.8.0_51 64bit"

А также

1
1
строка 0 роль 0 размер 1
дисплей: "1.8.0_51 64bit"

Два выхода появляются случайно. Вы можете найти role аргумент перешел в data() функция иногда будет нулевой. Роль нуля означает Qt::DisplayRole в Qt.

Итак, вот мой вопрос: если установлено textRole из ComboBox означает data role устанавливается равным значению textRole. Почему должен data role иногда становится Qt::DisplayRole? Это ошибка ComboBox?

1 ответ

Решение

Это не мудрая идея, чтобы иметь неоднозначное сопоставление имени роли с идентификатором роли. Отображение должно быть 1:1. Собственный Qt DisplayRole уже назван display, Назовите что-нибудь еще, что все еще является допустимым идентификатором js, или используйте Qt как есть.

Другие вопросы по тегам