这是 Qt Quick ComboBox 中的错误吗?
Posted
技术标签:
【中文标题】这是 Qt Quick ComboBox 中的错误吗?【英文标题】:Is this a bug in Qt Quick ComboBox? 【发布时间】:2015-07-31 07:04:24 【问题描述】:我使用QAbstractListModel
在 Qt Quick 中为ComboBox
创建自定义模型。
头文件中的代码:
#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)
我认为在我设置ComboBox
的textRole
之后,显示角色应该命名为“显示”,这是我根据m_roleNames.insert(Display, "display");
自定义模型中的角色Display
。但这并不总是正确的。
这是上面代码的qDebug()<<
输出:
1 1 第 0 行角色 260 大小 1 显示:“1.8.0_51 64bit”
还有
1 1 第 0 行角色 0 大小 1 显示:“1.8.0_51 64bit”
这两个输出是随机出现的。您会发现传递给data()
函数的role
参数有时会为零。 零角色在 Qt 中表示Qt::DisplayRole
。
所以这是我的问题:如果设置textRole
of ComboBox
意味着data role
设置为等于textRole 的值。为什么data role
有时会变成Qt::DisplayRole
?是ComboBox
的bug吗?
【问题讨论】:
【参考方案1】:角色名称到角色 ID 的映射不明确是不明智的做法。映射必须是 1:1。 Qt 自己的DisplayRole
已经命名为display
。将您的名称命名为仍然是有效 js 标识符的其他名称,或按原样使用 Qt。
【讨论】:
以上是关于这是 Qt Quick ComboBox 中的错误吗?的主要内容,如果未能解决你的问题,请参考以下文章
Qml Qt Quick Control 2:Text和ComboBox的字体大小区别