将 SelectionDialog 模型设置为继承 QAbstractListModel 的模型;没有项目显示

Posted

技术标签:

【中文标题】将 SelectionDialog 模型设置为继承 QAbstractListModel 的模型;没有项目显示【英文标题】:Setting the SelectionDialog model to a model inheriting QAbstractListModel; no items displayed 【发布时间】:2011-12-15 17:12:21 【问题描述】:

我无法在 qml 的 SelectionDialog 中显示 C++ 中定义的模型中的项目。我正在尝试为 Meego 操作系统制作应用程序。

如果我在 ListView 中显示项目,一切都会按预期工作并显示项目。但是,如果我尝试在 SelectionDialog 中显示它们,我会得到一个空列表。

这里有一些代码:

语言模型.h:

#ifndef LANGUAGEMODEL_H
#define LANGUAGEMODEL_H

#include <baza/language.h>
#include <QObject>
#include <QAbstractListModel>

class LanguageModel: public QAbstractListModel

    Q_OBJECT
public:
    enum LanguageRoles  
        RoleLanguageName = Qt::DisplayRole,
        RoleLanguageCode = Qt::UserRole,
        RoleId = Qt::UserRole+1,
        RoleChosen = Qt::UserRole+2
    ;

    LanguageModel(QObject *parent = 0);

    void addLanguge(const Language &language);
    void clear();

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

    QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;

private:
    QList<Language> m_languages;
;

#endif // LANGUAGEMODEL_H

语言模型.cpp:

#include "languagemodel.h"
#include <QDebug>

LanguageModel::LanguageModel(QObject *parent)
    : QAbstractListModel(parent)

    QHash<int, QByteArray> roles;

    roles[RoleLanguageName]="name";
    roles[RoleLanguageCode]="code";
    roles[RoleId]="id";
    roles[RoleChosen]="chosen";

    setRoleNames(roles);


void LanguageModel::addLanguge(const Language &language)
    beginInsertRows(QModelIndex(), rowCount(), rowCount());
    m_languages << language;
    endInsertRows();


int LanguageModel::rowCount(const QModelIndex & parent) const  
    return m_languages.count();


void LanguageModel::clear()
    for (int i=0; i<m_languages.count(); i++)
    
        beginRemoveRows(QModelIndex(), 0, 0);
        m_languages.removeAt(0);
        endRemoveRows();
    


QVariant LanguageModel::data(const QModelIndex & index, int role) const  
    if (index.row() < 0 || index.row() > m_languages.count())
        return QVariant();

    const Language &language = m_languages[index.row()];
    if (role == RoleLanguageName)
        return language.getName();
    else if (role == RoleLanguageCode)
        return language.getCode();
    else if (role == RoleChosen)
        return language.isChosen();
    else if (role == RoleId)
        return language.getId();

    return QVariant();

从 handler.cpp 中添加语言,例如:

//(...)
for(unsigned int i = 0; i < listLanguages.size(); i++)

    Language language = listLanguages.at(i);

    modelLanguages.addLanguge(language);

//(...)
ctxt->setContextProperty("modelLanguages", &modelLanguages);

在哪里 modelLanguages 是一个 LanguageModel。

我想在 Settings.qml 中显示列表:

//(...)
SelectionDialog 
    id: dialogLanguages

    titleText: qsTr("Select language")
    model: modelLanguages
    delegate: Text   text: name

当我打开 dialogLanguages 时,我只能看到标题“选择语言”而没有模型中的任何项目。

如果我将它用作模型,它可以正常工作:

model: ListModel 
    ListElement  name: "ListElement #1" 
    ListElement  name: "ListElement #2" 
    ListElement  name: "ListElement #3" 

另外,正如我已经提到的,如果我将 modelLanguages 设置为 ListView 中的模型,则所有项目都会正确显示。

任何人都可以帮助并告诉我我在这里做错了什么以及我必须进行哪些更改才能使其正常工作。

感谢任何帮助!

谢谢!

【问题讨论】:

【参考方案1】:

好的,我设法解决了!我在 cmets 中找到了关于灵魂的提示:https://qt.gitorious.org/qt-components/qt-components/merge_requests/887#

我需要向继承 QAbstractListModel 的模型添加计数属性。

我的 LanguageModel.h 现在看起来像这样:

class LanguageModel: public QAbstractListModel

    Q_OBJECT

    Q_PROPERTY(int count READ count NOTIFY countChanged)

    //(...)
public:
    //(...)
    int count();
    //(...)
signals:
    void countChanged(int newCount);
    //(...)

我在 LanguageModel.cpp 中添加了需要的方法:

//(...)
int LanguageModel::count()
    return m_languages.count();

//(...)

当计数发生变化(添加语言和清除模型时)时,我还发出了一个信号:

 emit countChanged(m_languages.count());

现在它开始工作了。 :)

我希望这对某人有所帮助。

再见!

【讨论】:

顺便提一下,这在模拟器上运行正常。当我尝试在真实设备(诺基亚 N9)上运行它时,我得到了一个空列表。这可能是因为设备上的 SelectionDialog.qml 仍然存在错误。为了解决这个问题,我用固定的 SelectionDialog.qml 的内容制作了一个 MySelectionDialog.qml,可以在这里找到:SelectionDialog.qml。

以上是关于将 SelectionDialog 模型设置为继承 QAbstractListModel 的模型;没有项目显示的主要内容,如果未能解决你的问题,请参考以下文章

在 ForeignKey Django 模型上继承或设置选择

Struts2 模型驱动动作中的继承可能吗?

将继承的属性类型指定为特定子项

7.28 盒子模型

Tastypie 从继承的模型中访问字段

如果将一个类设置为abstract,则此类必须被继承使用