loading data from database to expose in qml

北慕城南 提交于 2019-12-13 02:27:09

问题


I am new to QML, so please forgive my lack of knowledge.

I am loading some data from my database - after clicking in a button - and I want to fill a ListView with it.

This is my ListView:

    Rectangle {
    id:tblKules
    anchors.horizontalCenter: parent.horizontalCenter
    width: menuListaItem.width
    height:300
    visible:false
    color: "#e5e6e8"

    ListView {
        id: listView
        anchors.fill: parent; anchors.margins: 5
        model: mainController.listaDispositivos
        spacing: 1
        delegate: Component {
            Rectangle {
                id:item
                width: tblKules.width - 10
                height: 30
                color: tblKules.color
                RowLayout {
                    width: parent.width
                    anchors.verticalCenter: parent.verticalCenter
                    Text {
                        Layout.fillWidth: true
                        anchors.verticalCenter: parent.verticalCenter
                        text: nome
                        font.pixelSize: 14
                        color: "#7f7f7f"
                    }
                    Button {
                        text: "Visualizar"
                        anchors.verticalCenter: parent.verticalCenter
                        style: ButtonStyle {
                            background: Rectangle {
                                color:"#f2f2f2"
                            }

                            label: Text {
                                color:"#064356"
                                font.pixelSize: 13
                                font.capitalization: Font.Capitalize
                                text: control.text
                            }
                        }
                    }
                }
            }
        }
    }

    PropertyAnimation {
        id: animationAbrirLista;
        target: tblKules;
        property: "visible";
        to: true;
        duration: 300;
    }

    PropertyAnimation {
        id: animationFecharLista;
        target: tblKules;
        property: "visible";
        to: false;
        duration: 300;
    }
}

QMainController{
    id: mainController
}

I have a class called QMainController which controls this view in which I have this property that I fill with the loaded data:

Q_PROPERTY(QQmlListProperty<QDispositivo> listaDispositivos READ listaDispositivos NOTIFY listaDispositivosChanged)

void QMainController::list()
{
    m_listaDispositivos = m_dispositivoDAO.list();
    emit listaDispositivosChanged();
}


QQmlListProperty<QDispositivo> QMainController::listaDispositivos()
{
    return QQmlListProperty<QDispositivo>(this, m_listaDispositivos);
}

The data is being loaded fine, but I can't make it be displayed into the listView. How can I do that in a way it would reflect the changes that occur to the list?


回答1:


You didn't set the anchors (or a specific width and height) for your ListView. Try using a fixed model for debug purposes to make sure your views are okay:

import QtQuick 2.2

Rectangle
{
    ListView {
        anchors.fill: parent;
        model: 10; 
        delegate: Text {
            text: "item " + index;
        }
    }
}

If that works, replace the model with real data from your controller. If now the view's empty, something is wrong with the controller.

About updating the ListView: That happens automatically, if you emit the NOTIFY signal after altering the list model, there's nothing else to care about.

Edit

I would go with QList instead of QQmlListProperties. Take a look at this code, it shows how to set up a basic ListView, where the model is exposed from C++:

MyEntry.h

#pragma once

#include <QObject>
#include <QString>

class MyEntry : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString title READ getTitle WRITE setTitle NOTIFY titleChanged);
    Q_PROPERTY(QString subTitle READ getSubTitle WRITE setSubTitle NOTIFY subTitleChanged);
private:
    QString m_title;
    QString m_subTitle;
public:
    void setTitle(QString title);
    void setSubTitle(QString subTitle);
    QString getTitle();
    QString getSubTitle();
signals:
    void titleChanged();
    void subTitleChanged();
};

MyEntry.cpp

#include "MyEntry.h"

void MyEntry::setTitle(QString title) {
    this->m_title = title;
    emit titleChanged();
}

void MyEntry::setSubTitle(QString subTitle) {
    this->m_subTitle = subTitle;
    emit subTitleChanged();
}

QString MyEntry::getTitle() {
    return this->m_title;
}

QString MyEntry::getSubTitle() {
    return this->m_subTitle;
}

MyController.h

#pragma once

#include <QObject>

class MyEntry;

class MyController : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QList<QObject*> entries READ getEntries WRITE setEntries NOTIFY entriesChanged);
private:
    QList<QObject*> m_entries;
public:
    MyController();
    static MyController* instance;
    void setEntries(QList<QObject*> entries);
    void addEntry(MyEntry* entry);
    void removeEntry(MyEntry* entry);
    QList<QObject*> getEntries();
public slots:
    void init();
signals:
    void entriesChanged();
};

MyController.cpp

#include "MyController.h"
#include "MyEntry.h"

MyController* MyController::instance = 0;

MyController::MyController() {
    instance = this;
}

void MyController::init() {
    for(int i=0; i<10; ++i) {
        MyEntry* entry = new MyEntry();
        entry->setTitle(QString("title nr. ") + QString::number(i));
        entry->setSubTitle(QString("subTitle nr. ") + QString::number(i));

        this->m_entries.append(entry);
    }
    emit entriesChanged();
}

void MyController::setEntries(QList<QObject *> entries) {
    this->m_entries = entries;
    emit entriesChanged();
}

void MyController::addEntry(MyEntry* entry) {
    this->m_entries.append(entry);
    emit entriesChanged();
}

void MyController::removeEntry(MyEntry* entry) {
    this->m_entries.removeOne(entry);
    emit entriesChanged();
}

QList<QObject*> MyController::getEntries() {
    return this->m_entries;
}

Window.qml

import QtQuick 2.2

Rectangle {
    ListView {
        width: 400;
        height: parent.height;
        model: MyController.entries;
        delegate: Rectangle {
            width: parent.width;
            height: 30;
            color: index % 2 ? "#bbb" : "#999";
            Text {
                anchors.fill: parent;
                anchors.rightMargin: parent.width/2;
                text: modelData.title;
            }
            Text {
                anchors.fill: parent;
                anchors.leftMargin: parent.width/2;
                text: modelData.subTitle;   
            }
        }
    }
    Component.onCompleted: {
        MyController.init();
    }
}

Things to note

First of all, I know, it's a lot of code. But I had to search pretty much before finding a simple and clean example that shows how to set up a ListView in qml. This is what I found easy to understand and implement. So what happens there is, you first define your list entry like you need it. In the above example case it has two simple string properties that can be directly accessed in qml by their property names. Of course a member of MyEntry could again be a complex Object - as long as it derives from QObject and contains the Q_OBJECT macro. The MyController class basically shows how to handle a list of MyEntry Objects. One thing to mention: I wouldn't instantiate controllers via qml like you did. A qml Object may be destroyed at some point (depents on how you use your components) so that your controller could become null. Personally I prefer to instantiate controllers in C++ to exactly know about the object's lifecycle. To make the instance visible to qml, I initially register the controller as a context property to my QQuickView (make sure you finish your initial setup before showing the view, for example before you call showMaximized):

myQuickView->rootContext()->setContextProperty("MyController", MyController::instance);


来源:https://stackoverflow.com/questions/25629119/loading-data-from-database-to-expose-in-qml

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!