从数据库加载数据以在qml中公开

loading data from database to expose in qml

本文关键字:qml 数据库 加载 数据      更新时间:2023-10-16

我是QML的新手,所以请原谅我缺乏知识。

点击按钮后,我正在从数据库中加载一些数据,我想用它填充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
}

我有一个名为QMainController的类,它控制着这个视图,在这个视图中,我用加载的数据填充了这个属性:

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);
}

数据加载得很好,但我无法将其显示在listView中。我如何才能在某种程度上反映列表中发生的更改?

您没有为ListView设置锚点(或特定的宽度和高度)。尝试使用固定模型进行调试,以确保您的视图正常:

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

如果有效,请使用控制器中的真实数据替换模型。如果现在视图为空,则控制器出现问题。

关于更新ListView:这是自动发生的,如果您在更改列表模型后发出NOTIFY信号,则无需关心其他问题。

编辑

我会选择QList而不是QQmlListProperties。看看这段代码,它展示了如何设置一个基本的ListView,其中模型从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();
    }
}

需要注意的事项

首先,我知道,这是很多代码。但是,在找到一个简单明了的示例来展示如何在qml中设置ListView之前,我必须进行大量搜索。这是我发现很容易理解和实现的。因此,首先按照需要定义列表条目。在上面的示例中,它有两个简单的字符串属性,可以通过它们的属性名称在qml中直接访问。当然,MyEntry的成员也可以是一个复杂的Object,只要它派生自QObject并包含Q_Object宏即可。MyController类基本上展示了如何处理MyEntry对象的列表。有一点要提:我不会像你那样通过qml实例化控制器。qml对象可能会在某个时刻被销毁(取决于您如何使用组件),因此您的控制器可能会变为null。就我个人而言,我更喜欢用C++实例化控制器,以准确地了解对象的生命周期。为了使该实例对qml可见,我最初将控制器注册为QQuickView的上下文属性(确保在显示视图之前完成初始设置,例如在调用showMaximized之前):

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