QT c++和qml交互实例

一、demo效果图

该实例,主要是在已有的QWidget工程中,加入qml工程,方便qml项目的开发与维护,让qml开发者更好的上手qml。

(1)展示了c++和qml常见的交互方式。
(2)qwidget工程如何加载qml工程,如何加载自己实现的qml tool库。
(3)创建无边框qml界面,支持拖拽,窗口的缩小与展开,界面的分段实现。
(4)展示一个简单的堆栈窗口(SwipeView),相当于QStackedWidget,管理多个子窗口页面。
(5)实现一个简单的列表框(ListView),相当于QListWidget,定时请求网络数据,展示学生信息,将view和model进行分离,降低界面与数据的耦合。
(6)点击学号、年龄,实现了列表数据的排序。

在这里插入图片描述



二、c++和qml交互的基本方式

两者的交互是核心,简单学习后,可以快速上手。方式有很多种,有的比较繁杂,不易理解,此处只使用了最方便使用的方法,满足基本的交互。基本的方式不外乎有四种。

  • qml 调用 C++ 类对象
  • C++ 类对象调用 qml
  • qml 给 C++ 发送信号
  • C++ 给 qml 发送信号
1、qml 调用 C++ 类对象

需要先将C++类(MainQuickView、MyWindow)注册。和qml相关的C++类,最好都进行注册。

// cpp
class MainQuickView : public QQuickView
{
   
    Q_OBJECT
public:
    MainQuickView(QQuickView *parent = nullptr);
    ~MainQuickView() override;
    void initialzeUI();
protected:
};

void MainQuickView ::initialzeUI()
{
   
    // 注册,为了qml中可以直接访问C++对象
    this->rootContext()->setContextProperty("myQuickView", this);
    MyWindow *w = new MyWindow();
    this->rootContext()->setContextProperty("myWindow", w);
	...
}

这样C++的信号public槽函数Q_INVOKABLE 修饰的类成员函数

// cpp
class MyWindow : public QWidget
{
   
      Q_OBJECT
  public:
      MyWindow();
      // Q_INVOKABLE可以将C++函数暴漏给qml引擎,注册到元对象系统
      Q_INVOKABLE void invokableMethod();
  signals:
      void dataChanged();
  public slots:
  	  void refresh();
};

就可以在qml中调用

// main.qml
Rectangle {
   
    id: root
    width: 1200
    height: 800
    onClicked: {
   
        myWindow.showNormal(); // showNormal是QWidget父类的槽函数
    }
}

2、C++ 类对象调用 qml

需要先找到你想访问的qml中,名为"topRect"的QQuickItem对象

// cpp
QQuickItem* topRect = this->rootObject()->findChild<QQuickItem*>("topRect");

然后再访问qml实现的函数,“setTitleText”,该函数标题3展示(qml 给 C++ 发送信号)

// cpp
QMetaObject::invokeMethod(topRect, "setTitleText", Q_ARG(QVariant, QString::fromLocal8Bit("Qml窗口标题")));

3、qml 给 C++ 发送信号

qml发送信号

// qml
Rectangle {
   
    id: root
    
    signal sendTopRectPos(var x, var y)  // 定义信号

    function setTitleText(text) {
   
        titleText.text = text
    }
    
	MouseArea {
   
	    // ... 
        property point clickPos: "0, 0"

        onPressed: {
   
            clickPos = Qt.point(mouse.x, mouse.y)
        }

        onPositionChanged: {
   
            var delta = Qt.point(mouse.x - clickPos.x, mouse.y - clickPos.y)
            sendTopRectPos(delta.x, delta.y)  // 发送信号
        }
    }
}

C++绑定槽函数,该操作可以实现无边框窗口的拖拽

// cpp
QQuickItem* topRect = this->rootObject()->findChild<QQuickItem*>("topRect");
    if (topRect) {
   
        connect(topRect, SIGNAL(sendTopRectPos(QVariant, QVariant)),
                this, SLOT(onSendTopRectPos(QVariant, QVariant)));

4、C++ 给 qml 发送信号

C++发送信号

// cpp
void MainQuickView::minMaxQmlWindow()
{
   
	int nStudent = 10;
    emit refreshStuCount(nStudent); // 发送信号
}

qml绑定槽函数

// qml
Rectangle {
   
    id: root
    function onRefreshStuCount(nStudent){
   
        // ...
    }

    Component.onCompleted: {
   
        mainQuickView.refreshStuCount.connect(onRefreshStuCount)  // 绑定qml函数
    }


三、关键代码

1、工程结构图

在这里插入图片描述

2、c++代码
MainWindow.cpp
MainWindow::MainWindow(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MainWindow)
    , m_pQuickVew(nullptr)
{
   
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
   
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
   
    if (!m_pQuickVew)
    {
   
    	// 加载qml包含两种方式,一种是QQuickView,一种是QQmlApplicationEngine
    	// 当前使用第一种方式,MainQuickView继承自QQuickView
        m_pQuickVew = new MainQuickView();
        m_pQuickVew->setObjectName("quickView");
    }

    m_pQuickVew->show();
}
MainQuickView.cpp
static const char* s_mainPath = "qrc:/qml/main.qml";

MainQuickView::MainQuickView(QQuickView *parent)
    : QQuickView(parent)
    , m_bMin(false)
{
   
    this->setFlags(Qt::Window | Qt::FramelessWindowHint);
    this->setTitle(QString::fromLocal8Bit("图书馆"));
    initialize();
    setMoveable();
    setTitleData();
}

MainQuickView::~MainQuickView()
{
   
}

void MainQuickView::initialize()
{
   
    // 初始化view 和 model,降低耦合,提高可维护性
    if (!m_pStudentInfoView)
        m_pStudentInfoView = new StudentInfoView();

    if (!m_pStudentInfoModel)
        m_pStudentInfoModel = m_pStudentInfoView->getStudentInfoMode();

    // ...其他功能

    initialzeUI();
}

void MainQuickView::initialzeUI
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值