上面几期已经基本把软件的界面搭好了,接下来需要写功能部分,之前其实我已经写了通过公开的接口来获取指定基金代码的基金信息.

所以现在要做的,就是实现QML侧与C++侧的信号槽机制.这样才可以将QML侧添加删除基金的操作调用对应的C++写的功能.

先添加一个mainwork的cpp与h文件,创建一个MainWork类,将来用于处理所有与主界面有关的C++实现的功能.

#include "main_work.h"
#include <QDebug>

MainWork *MainWork::instance = 0;
Fund_HTTP_Manager *MainWork::fund_http_manager_instance = 0;
DataModel* MainWork::fund_info_list_data_model_instance = 0;
/*******************************************************************************
* Function Name  :  setFundInfoListDataModelInstance
* Description    :  设置单例
* Input          :  None
* Output         :  None
* Return         :  None
*******************************************************************************/
DataModel* MainWork::setFundInfoListDataModelInstance(DataModel* Instance)
{
    if(fund_info_list_data_model_instance == 0)
    {
        fund_info_list_data_model_instance = Instance;
    }
    return fund_info_list_data_model_instance;
}

/*******************************************************************************
* Function Name  :  getInstance
* Description    :  获取单例
* Input          :  None
* Output         :  None
* Return         :  None
*******************************************************************************/
MainWork *MainWork::getInstance()
{
    if(instance == 0)
    {
        instance = new MainWork();
    }
    return instance;
}


/*******************************************************************************
* Function Name  :  MainWork
* Description    :  构造函数
* Input          :  None
* Output         :  None
* Return         :  None
*******************************************************************************/
MainWork::MainWork(QObject *parent):QObject(parent)
{
    fund_http_manager_instance = Fund_HTTP_Manager::getInstance();
    //fund_http_manager_instance->Slot_QueryFundInfo("320007");
}


/*******************************************************************************
* Function Name  :  Slot_AddFund
* Description    :  添加基金
* Input          :  QString fund_code
* Output         :  None
* Return         :  None
*******************************************************************************/
void MainWork::Slot_AddFund(QString fund_code)
{
    qDebug() << "Slot_AddFund被触发:"+fund_code;
}

/*******************************************************************************
* Function Name  :  Slot_DelFund
* Description    :  添加基金
* Input          :  QString fund_code
* Output         :  None
* Return         :  None
*******************************************************************************/
void MainWork::Slot_DelFund(QString fund_code)
{
    qDebug() << "Slot_DelFund被触发:"+fund_code;
}


/*******************************************************************************
* Function Name  :  Slot_RefreshFundInfo
* Description    :  刷新基金信息
* Input          :  None
* Output         :  None
* Return         :  None
*******************************************************************************/
void MainWork::Slot_RefreshFundInfo(void)
{
    qDebug() << "Slot_RefreshFundInfo被触发";
}

对应的h文件.

#ifndef MAIN_WORK_H
#define MAIN_WORK_H

#include <QObject>
#include "fund_http_manager.h"
#include "fund_list.h"
class MainWork : public QObject
{
    Q_OBJECT
public:

    static MainWork *getInstance();
    static DataModel* setFundInfoListDataModelInstance(DataModel* Instance);
signals:


public slots:
    void Slot_AddFund(QString fund_code);
    void Slot_DelFund(QString fund_code);
    void Slot_RefreshFundInfo(void);

private:
    explicit MainWork(QObject *parent = 0);
    static MainWork* instance;
    static Fund_HTTP_Manager* fund_http_manager_instance;
    static DataModel* fund_info_list_data_model_instance;

};


#endif // MAIN_WORK_H

在MainWork里声明了几个对外的槽函数:

void Slot_AddFund(QString fund_code);
void Slot_DelFund(QString fund_code);
void Slot_RefreshFundInfo(void);

接下来,就需要想办法将QML的信号与这些槽函数连接.

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

Window {
    id: main_window
    visible: true
    width: 640
    height: 480
    title: qsTr("苏阳基金查看器v1.0")
    signal sig_add_fund(string fund_code)
    signal sig_remove_fund(string fund_code)

    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
    }

    TButton{
        width: 100
        height: 50
        label.text: "添加基金"
        anchors.right: parent.right
        anchors.rightMargin: 10
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 10
        label.font.bold: true
        label.color: "#FFF"
        background.color: "#FFAD99"
        onClicked:
        {
            add_fund_window.show()
        }
    }
    Add_fund{
        id:add_fund_window
        onAdd_fund_info:
        {
            console.log("收到添加基金信号"+fund_code)
            main_window.sig_add_fund(fund_code)
        }
    }
    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_window.sig_remove_fund(fundCode)
               }
           }
    }
}

上面是现在的main.qml内容,在最外的Window组件内定义了两个信号:

signal sig_add_fund(string fund_code)
signal sig_remove_fund(string fund_code)

并在适合的地方发射这两个信号.

然后开始解决怎么连接这两个信号的问题了.在main.cpp里增加如下代码:

 QObject::connect(engine.rootObjects()[0], SIGNAL(sig_add_fund(QString)),main_work_instance, SLOT(Slot_AddFund(QString)));

    QObject::connect(engine.rootObjects()[0], SIGNAL(sig_remove_fund(QString)),main_work_instance, SLOT(Slot_DelFund(QString)));

通过这种方式即可将两个信号与对应的槽连接在一起,这里说一下QML的类型与C++的类型的转换的问题.QML的类型与C++的类型在信号槽机制传值的时候是可以自动转换的,这个的确很方便.

Qt TypeQML Basic Type
boolbool
unsigned int, intint
doubledouble
float, qrealreal
QStringstring
QUrlurl
QColorcolor
QFontfont
QDateTimedate
QPoint,QPointFpoint
QSize,QSizeFsize
QRect,QRectFrect
QMatrix4x4matrix4x4
QVector2D,QVector3D,QVector4Dvector2d,vector3d,vector4d
Enums declared with Q_ENUM() or Q_ENUMS()enumeration

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