在 QT 中集成 C++ 模型时清空 ListView

Empty ListView when integrating C++ Models in QT

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

todomodel.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;
}

todomodel.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, const QVariant &value,
                 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, 0, "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 个条目,而是显示空列表,如下所示。请指导我哪里出错了。

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

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

    // FIXME: Implement me!
    return 100;
}