【问题标题】:loading data from database to expose in qml从数据库加载数据以在 qml 中公开
【发布时间】:2014-09-02 17:33:03
【问题描述】:

我是 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 中。我怎样才能以反映列表发生变化的方式做到这一点?

【问题讨论】:

    标签: c++ qml qlistview qlist


    【解决方案1】:

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

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

    【讨论】:

    • 我确实有锚。这只是这个想法的简短介绍。
    • 请发布您遇到问题的相同代码,否则我们无法真正找到解决方案,不得不做出错误的假设!如果您遇到问题的代码太大,请将其缩减为一个小场景,以便我们重现您遇到的错误!
    • 我见过一些使用 QQmlListProperty 的示例,但应用在加载列表后会崩溃
    • 是的,QQmlListProperties 要复杂得多,对于简单的列表,我总是更喜欢QList&lt;QObject*&gt;!
    • 目前,我只尝试显示名称,但稍后我需要更多信息来打开与 rowData 相关的另一个视图
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多