无法使用QML修改用C ++创建的模型

时间:2019-03-20 22:36:22

标签: c++ qt qml

已解决:我做了所有类似eyllanesc的回答,并且在我的FirstPage.qml中 委托我访问模型数据的位置,我将modelData放在名称之前。 以前我在FirstPage.qml委托中使用过:名称,已完成和 未完成,现在我使用modelData.name,modelData.completed和 modelData.uncomplete。现在一切都很好。

我是QT / QML的新手,我尝试过但找不到解决问题的答案。

我在QML中使用模型(在c ++中创建)。当应用程序启动时,一切都很好,但是当我尝试添加新元素进行建模时,它不会显示在QML中。模型从一开始就是一样。

我有类modcontroller,并且在其中创建列表。

modcontroller.h

#ifndef MODCONTROLLER_H
#define MODCONTROLLER_H

#include <QObject>
#include <list.h>

class modcontroller : public QObject
{
    Q_OBJECT

public:
    explicit modcontroller(QObject *parent = nullptr);

    QList<QObject*> getList();

    Q_INVOKABLE void addList(QString nam);

signals:
    void listChanged();

public slots:

private:
    QList<QObject*> m_dataList;
};

#endif // MODCONTROLLER_H

modcontroller.cpp

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

modcontroller::modcontroller(QObject *parent) : QObject(parent)
{
    m_dataList.append(new List("Test"));
}

QList<QObject *> modcontroller::getList()
{
    return m_dataList;
}

void modcontroller::addList(QString nam)
{
    m_dataList.append(new List(nam));
    qDebug() << "Function addList called";

    qDebug() << m_dataList;
}

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

#include "list.h"
#include "modcontroller.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);


    QQmlApplicationEngine engine;


    modcontroller controller;
    engine.rootContext()->setContextProperty("myModel", QVariant::fromValue(controller.getList()));
    engine.rootContext()->setContextProperty("controller",&controller);

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;



    return app.exec();
}

在QML文件中,我具有带有model: myModel的ListView和带有

的按钮
onClicked: {
                controller.addList(textInput.text)
                myStackView.push(firstPage)
            }

当我单击“创建”时,我仅看到开始时创建的第一项“测试”,但在控制台中却看到了:

Function addList called
(List(0x2b7e60bc2c0), List(0x2b82d5891b0))

谢谢。

main.qml

    ApplicationWindow {
        visible: true
        width: 580
        height: 360
        title: qsTr("Hello World")

        StackView{
            id: myStackView
            initialItem: firstPage
            anchors.fill: parent
        }

        Component{
            id: firstPage
            FirstPage{}
        }

        Component{
            id: createNewListPage
            CreateNewListPage{}
        }

    }

FirstPage.qml

Item {    
    ListView{
                id: lists
                width: 150
                height: childrenRect.height
                x: 15
                y: 70

                model: myModel

                delegate: Row{
                    width: 150
                    height: 25
                    spacing: 5

                    Rectangle{
                        width: {
                            if(uncompleted < 3){return 3;}
                            else if(uncompleted < 6){return 6;}
                            else {return 10;}
                        }
                        height: {
                            if(uncompleted < 3){return 3;}
                            else if(uncompleted < 6){return 6;}
                            else {return 10;}
                        }
                        radius: 10
                        color: "#494949"
                        anchors.verticalCenter: parent.verticalCenter
                    }
                    Button {
                        id:button1
                        height: 23

                        contentItem: Text {
                            id: textTask
                            text: name
                            font.underline: true
                            color: "blue"
                            font.bold: true
                            font.pointSize: 10
                            height: 20
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.left: parent.left
                        }

                        background: Rectangle {
                            id: rectangle
                            color: "transparent"
                        }
                        states:[
                            State {
                                name: "Hovering"
                                PropertyChanges {
                                    target: textTask
                                    color: "white"
                                    font.bold: true
                                    font.underline: false
                                }
                                PropertyChanges {
                                    target: rectangle
                                    color: "blue"
                                }
                            }]

                        MouseArea{
                            hoverEnabled: true
                            anchors.fill: button1
                            onEntered: { button1.state='Hovering'}
                            onExited: { button1.state=''}
                        }
                    }
                    Text{
                        font.pointSize: 8
                        text: {
                            if(uncompleted == 0)return "";
                            return "- " + uncompleted + " left";
                        }
                        color: "#494949"
                        anchors.verticalCenter: parent.verticalCenter
                    }
                }
            }
}

CreateNewListPage.qml

Item {
   Rectangle{
       width: 580
       height: 360

       Rectangle{
        width: 350
        height: 30
        y: 100
        x: 30
        border.color: "#7b9cd3"
        border.width: 1

        TextInput {
            id: textInput
            anchors.topMargin: 3
            cursorVisible: true
            anchors.fill: parent
            font.bold: true
            font.pointSize: 14
        }

    }



       Button{
                height: 20
                text: "Create this list"
                onClicked: {
                    controller.addList(textInput.text)
                    myStackView.push(firstPage)
                }

                background: Rectangle{
                    id: rect1
                    anchors.fill: parent
                    radius: 20
                    border.color: "#88b6cf"
                    gradient: Gradient {
                            GradientStop { position: 0.0; color: "#fcfefe" }
                            GradientStop { position: 1.0; color: "#d5e8f3" }
                    }
                }

            }

     }
}

1 个答案:

答案 0 :(得分:0)

列表是一个虚拟模型,因为它本身不会通知视图是否发生任何更改(例如元素数量),因此针对您的情况的解决方案是使其成为mod_controller的Q_PROPERTY,然后在添加项目时,标志listChanged将通知视图某些内容已更改,因此需要重新粉刷。由于Q_PROPERTY可在QML中访问,因此不必与控制器分开导出列表,因此解决方案是:

modcontroller.h

#ifndef MODCONTROLLER_H
#define MODCONTROLLER_H

#include <QObject>

class modcontroller : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QList<QObject *> lists READ getList NOTIFY listsChanged) // <---
public:
    explicit modcontroller(QObject *parent = nullptr);
    QList<QObject *> getList() const;
    Q_INVOKABLE void addList(const QString &nam);
    Q_SIGNAL void listsChanged();
private:
    QList<QObject*> m_dataList;
};

#endif // MODCONTROLLER_H

modcontroller.cpp

#include "modcontroller.h"
#include "list.h"

#include <QDebug>

modcontroller::modcontroller(QObject *parent) : QObject(parent)
{
    m_dataList.append(new List("Test"));
}

QList<QObject *> modcontroller::getList() const
{
    return m_dataList;
}

void modcontroller::addList(const QString & nam)
{
    m_dataList.append(new List(nam));
    qDebug() << "Function addList called";
    qDebug() << m_dataList;
    Q_EMIT listsChanged(); // <---
}

main.cpp

#include "modcontroller.h"

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    modcontroller controller;
    engine.rootContext()->setContextProperty("controller",&controller);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

对于QML,绑定是通过控制器的Q_PROPERTY列表完成的:

ListView{
    // ...
    model: controller.lists // <---
    // ...