从数据库加载数据以在qml中公开 [英] loading data from database to expose in qml

查看:208
本文介绍了从数据库加载数据以在qml中公开的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

我正在从数据库中加载一些数据-单击按钮后-我想用它填充ListView.

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

这是我的ListView:

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
}

我有一个名为QMainController的类,该类控制此视图,在该视图中,我具有此属性,该属性填充了加载的数据:

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

数据可以很好地加载,但是我无法使其显示在listView中.我该怎么做才能反映出列表中发生的更改?

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?

推荐答案

您没有为Lis​​tView设置锚点(或特定的宽度和高度).尝试将固定模型用于调试目的,以确保您的视图正确:

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.

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

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.

我会选择QList而不是QQmlListProperties.看一下这段代码,它展示了如何设置基本的ListView,其中的模型是从C ++公开的:

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++:

#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的成员也可以是复杂的对象-只要它源自QObject并包含Q_OBJECT宏. MyController类基本上说明了如何处理MyEntry对象的列表.要提的一件事:我不会像您那样通过qml实例化控制器.一个qml对象可能会在某个时候被破坏(取决于您如何使用组件),以便您的控制器可能为空.就我个人而言,我更喜欢在C ++中实例化控制器以确切了解对象的生命周期.为了使实例对qml可见,我首先将控制器注册为QQuickView的上下文属性(确保在显示视图之前完成初始设置,例如,在调用showMaximized之前):

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

这篇关于从数据库加载数据以在qml中公开的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆