在 QT

问题描述

创建的 C++ 列表模型与 QML 集成以填充列表视图,其中包含一个复选框和 100 个条目的文本视图,如下所示

tod​​omodel.cpp 文件

#include "todomodel.h"

TodoModel::TodoModel(QObject *parent)
    : QAbstractListModel(parent)
{
}

int TodoModel::rowCount(const QModelIndex &parent) const
{
    if (!parent.isValid())
        return 0;

    // FIXME: Implement me!
    return 100;
}

QVariant TodoModel::data(const QModelIndex &index,int role) const
{
    if (!index.isValid())
        return QVariant();

    // FIXME: Implement me!
    switch(role) {
        case DoneRole:
            return QVariant(false);
        case DescriptionRole:
            return QVariant(QStringLiteral("Test"));
    }


    return QVariant();
}

bool TodoModel::setData(const QModelIndex &index,const QVariant &value,int role)
{
    if (data(index,role) != value) {
        // FIXME: Implement me!
        emit dataChanged(index,index,QVector<int>() << role);
        return true;
    }
    return false;
}

Qt::ItemFlags TodoModel::flags(const QModelIndex &index) const
{
    if (!index.isValid())
        return Qt::NoItemFlags;

    return Qt::ItemIsEditable; // FIXME: Implement me!
}

QHash<int,QByteArray> TodoModel::roleNames() const
{
    QHash<int,QByteArray> names;
    names[DoneRole] = "done";
    names[DescriptionRole] = "description";
    return names;
}

tod​​omodel.h 文件

#ifndef TodoMODEL_H
#define TodoMODEL_H

#include <QAbstractListModel>

class TodoModel : public QAbstractListModel
{
    Q_OBJECT

public:
    explicit TodoModel(QObject *parent = 0);

    enum {
        DoneRole = Qt::UserRole,DescriptionRole
    };

    // Basic functionality:
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;

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

    // Editable:
    bool setData(const QModelIndex &index,int role = Qt::EditRole) override;

    Qt::ItemFlags flags(const QModelIndex& index) const override;

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

#endif // TodoMODEL_H

TodoList.qml 文件


import Todo 1.0

Frame {
    ListView {
        //Listview needs model,a delegate,//the size determines the user interactive:
        implicitHeight: 250//same as wrap content in android
        implicitWidth: 250
        clip: true

        model: TodoModel{}

        delegate: RowLayout{
            width: parent.width
            CheckBox {
                checked: model.done
                onClicked: model.done = checked
            }
            TextField {
                Layout.fillWidth: true
                text: model.description
                onEditingFinished: model.description = text
            }
        }
    }
}

main.cpp 文件

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickStyle>

#include "todomodel.h"

int main(int argc,char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc,argv);
    QQuickStyle::setStyle("Material");

    qmlRegisterType<TodoModel>("Todo",1,"TodoModel");

    QQmlApplicationEngine engine;
    engine.load(QUrl(Qlatin1String("qrc:/main.qml")));

    return app.exec();
}

main.qml 文件

import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3

applicationwindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    TodoList {
        anchors.centerIn: parent
    }
}

结果: 它没有显示 100 个条目,而是显示如下所示的空列表。请指导我哪里出错了。

enter image description here

解决方法

当父级无效(根级)时,您指定模型有 0 个零行。您应该将 return 0; 更改为 return 100;

int ToDoModel::rowCount(const QModelIndex &parent) const
{
    if (parent.isValid()) //changed here
        return 0;

    // FIXME: Implement me!
    return 100;
}