上一次咱们讲了MVC概念,并且按MVC的方式在QML里创建了一个ListModel用于存放显示的数据,但是实际上数据在咱们这个应用上一般来自C++一侧,所以还是需要能在C++那边提供数据,在QML上显示才行,因为也刚刚学这部分,所以理解也不深.目前我的理解是创建一个 QAbstractListModel 的子类,然后在这个类里实现一个存储所有对应的KV数据的机制并对外提供增删读写的标准接口.然后把这个类在C++侧实例化然后注册到QML上下文,就可以在QML侧调用了.

直接贴代码吧.

fund_list.h文件内容:

#ifndef FUND_LIST_DATA_MODEL_H
#define FUND_LIST_DATA_MODEL_H


#include <QAbstractListModel>


class Data
{
public:
    Data(void);
    Data(const QString &fund_name,int fund_code,double fund_net_worth,double fund_expect_worth,double fund_expect_growth,const QString &fund_net_worth_date,const QString &fund_expect_worth_date);

    QString fund_name() const;
    int fund_code() const;
    double fund_net_worth() const;
    double fund_expect_worth() const;
    double fund_expect_growth() const;
    QString fund_net_worth_date() const;
    QString fund_expect_worth_date() const;

private:

    QString fund_name_;
    int fund_code_;
    double fund_net_worth_;
    double fund_expect_worth_;
    double fund_expect_growth_;
    QString fund_net_worth_date_;
    QString fund_expect_worth_date_;
};


class DataModel : public QAbstractListModel
{
    Q_OBJECT

public:
    enum DataRoles{
            FundNameRole = Qt::UserRole + 1,
            FundCodeRole,
            FundNetWorthRole,
            FundExpectWorthRole,
            FundExpectGrowthRole,
            FundNetWorthDateRole,
            FundExpectWorthDateRole
        };

    explicit DataModel(QObject *parent = nullptr);
       ~DataModel();

    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
        QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;

        // Add data:
        Q_INVOKABLE void insert(int index,const Data &data) ;

        // Remove data:
        Q_INVOKABLE void remove(int index);
        Q_INVOKABLE void append(const QString &fund_name,int fund_code,double fund_net_worth,double fund_expect_worth,double fund_expect_growth,const QString &fund_net_worth_date,const QString &fund_expect_worth_date);
        int count() const;

    protected: // interface QAbstractListModel
        virtual QHash<int, QByteArray> roleNames() const;

    private:
        QList<Data> dataList_;

};

#endif // FUND_LIST_DATA_MODEL_H

fund_list.c文件内容:

#include "fund_list.h"

Data::Data(void)
{
    fund_name_= "NULL";
    fund_code_ = 0;
    fund_net_worth_ = 0.0;
    fund_expect_worth_ = 0.0;
    fund_expect_growth_ = 0.0;
    fund_net_worth_date_ = "NULL";
    fund_expect_worth_date_ = "NULL";
}

Data::Data(const QString &fund_name,int fund_code,double fund_net_worth,double fund_expect_worth,double fund_expect_growth,const QString &fund_net_worth_date,const QString &fund_expect_worth_date)
{
    fund_name_= fund_name;
    fund_code_ = fund_code;
    fund_net_worth_ = fund_net_worth;
    fund_expect_worth_ = fund_expect_worth;
    fund_expect_growth_ = fund_expect_growth;
    fund_net_worth_date_ = fund_net_worth_date;
    fund_expect_worth_date_ = fund_expect_worth_date;
}

QString Data::fund_name() const
{
    return fund_name_;
}
int Data::fund_code() const
{
    return fund_code_;
}

double Data::fund_net_worth() const
{
    return fund_net_worth_;
}

double Data::fund_expect_worth() const
{
    return fund_expect_worth_;
}

double Data::fund_expect_growth() const
{
    return fund_expect_growth_;
}

QString Data::fund_net_worth_date() const
{
    return fund_net_worth_date_;
}


QString Data::fund_expect_worth_date() const
{
    return fund_expect_worth_date_;
}


DataModel::DataModel(QObject *parent)
    : QAbstractListModel(parent)
{
}

DataModel::~DataModel()
{
}

int DataModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return dataList_.count();
}

QVariant DataModel::data(const QModelIndex &index, int role) const
{
    int row = index.row();
    if(row < 0 || row >= dataList_.count())
    {
        return QVariant();
    }
    const Data &data = dataList_[row];
    switch (role)
    {
    case FundNameRole:
        return data.fund_name();
    case FundCodeRole:
        return data.fund_code();
    case FundNetWorthRole:
        return data.fund_net_worth();
    case FundExpectWorthRole:
        return data.fund_expect_worth();
    case FundExpectGrowthRole:
        return data.fund_expect_growth();
    case FundNetWorthDateRole:
        return data.fund_net_worth_date();
    case FundExpectWorthDateRole:
        return data.fund_expect_worth_date();

    }

    return QVariant();
}


//dm : data model
QHash<int, QByteArray> DataModel::roleNames() const
{
    QHash<int, QByteArray> roles;
    roles[FundNameRole] = "fundName";
    roles[FundCodeRole] = "fundCode";
    roles[FundNetWorthRole] = "fundNetWorth";
    roles[FundExpectWorthRole] = "fundExpectWorth";
    roles[FundExpectGrowthRole] = "fundExpectGrowth";
    roles[FundNetWorthDateRole] = "fundNet_worthDate";
    roles[FundExpectWorthDateRole] = "fundExpectWorthDate";

    return roles;
    //    emit countChanged(m_data.count());
}

void DataModel::insert(int index, const Data &data)
{
    if(index < 0 || index > dataList_.count()) {
        return;
    }

    emit beginInsertRows(QModelIndex(), index, index);
    dataList_.insert(index, data);
    emit endInsertRows();
//    emit countChanged(m_data.count());
}

void DataModel::remove(int index)
{
    if(index < 0 || index >= dataList_.count()) {
        return;
    }

    beginRemoveRows(QModelIndex(), index, index);
    dataList_.removeAt(index);
    endRemoveRows();
}


void DataModel::append(const QString &fund_name,int fund_code,double fund_net_worth,double fund_expect_worth,double fund_expect_growth,const QString &fund_net_worth_date,const QString &fund_expect_worth_date)
{
    insert(count(), Data(fund_name,fund_code,fund_net_worth,fund_expect_worth,fund_expect_growth,fund_net_worth_date,fund_expect_worth_date));
}


int DataModel::count() const
{
    return rowCount(QModelIndex());
}

main.qml文件内容:

import QtQuick 2.12
import QtQuick.Window 2.12
import Toou2D 1.0
import "."

Window {
    id: window
    visible: true
    width: 640
    height: 480
    title: qsTr("苏阳基金查看器v1.0")


    ListView{
        anchors.right: parent.right
        anchors.rightMargin: 10
        anchors.left: parent.left
        anchors.leftMargin: 10
        anchors.top: parent.top
        anchors.topMargin: 10
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 30

        width: 600
        height: 400
        id:listView
        spacing: 10
        model:$Model
        delegate:delegate1
    }


    Component {
           id: delegate1
           Fund_info_box
           {
               fund_code:fundCode// 基金代码
               fund_name:fundName// 基金名称
               //fund_net_worth:fundNetWorth// 基金单位净值
               fund_expect_worth:"净值估算:"+fundExpectWorth// 基金净值估算
               fund_expect_growth:"净值估算日涨幅:"+fundExpectGrowth+"%"// 基金净单位净值估算日涨幅
               //fund_net_worth_date:fundNetWorthDate// 基金净值更新日期
               //fund_expect_worth_date:fundExpectWorthDate// 基金净值估算更新日期
               anchors.right: parent.right
               anchors.left: parent.left
               onRemove_fund_info_box:{
                console.log("Fund_Code:"+fundCode)
               }
           }
    }
}

main.cpp文件内容:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "fund_http_manager.h"
#include <QSslSocket>
#include "fund_list.h"
#include <QQmlContext>

int main(int argc, char *argv[])
{
    DataModel model;

    model.append("银河创新成长混合",519674,1.0,1.7447,-0.24,"123","123");
    model.append("诺安成长混合",320007,1.0,5.8416,-0.3,"123","123");
    model.append("招商中证白酒指数分级",161725,1.0,1.2081,3.43,"123","123");

    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    engine.rootContext()->setContextProperty("$Model",&model);

    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    qDebug()<<"QSslSocket="<<QSslSocket::sslLibraryBuildVersionString();
    qDebug() << "OpenSSL支持情况:" << QSslSocket::supportsSsl();
    //Fund_HTTP_Manager* tmp = Fund_HTTP_Manager::getInstance();
    //tmp->Slot_QueryFundInfo("320007");
    return app.exec();
}

实际的界面效果是这样的.


一个电子工程师的自我修养