QT通过QQuickWidget与QML之间的交互及实现(类似)仪表盘

1、在与qml通信的时候,需要把函数接口暴露给qml需要在函数前面加入Q_INVOKABLE关键字,且需要注意成员函数的公有或私有类型。

例如:

.h文件

 

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    Q_INVOKABLE QString sendData();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

 

.cpp文件

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QQuickItem>
#include <QQmlApplicationEngine>
#include <QQuickView>
#include <QQmlContext>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QUrl soucre("qrc:/qml/text.qml");
    ui->quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
    ui->quickWidget->rootContext()->setContextProperty("testData", this);
    ui->quickWidget->setSource(soucre);
    ui->quickWidget->setClearColor(QColor(Qt::transparent));
}

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

QString MainWindow::sendData()
{
    QString str = "blue";
    return str;
}

main.cpp

#include "mainwindow.h"
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QQuickView>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    MainWindow w;
    w.show();

    return a.exec();
}

text.qml

import QtQuick 2.0
import QtQuick.Controls 1.4
Rectangle{
    id:root;
    height:200;
    width:200;
    color: "red"
    Text {
        anchors.centerIn: parent
        text: qsTr("hello")
    }
    MouseArea{
        anchors.fill: parent;
        onClicked: {
            root.color = testData.sendData()
        }
    }
}

 2、利用quickWidget来进行数据传递

#include "dashboard.h"
#include "ui_dashboard.h"
#include <QQuickWidget>
#include <QQuickItem>
#include <QQmlApplicationEngine>
#include <QQuickView>
#include <QQmlContext>
#include <QDebug>


Dashboard::Dashboard(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Dashboard)
{
    ui->setupUi(this);
    QUrl soucre("qrc:/qml.qml");
    ui->quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
    ui->quickWidget->setSource(soucre);
    ui->quickWidget->setAttribute(Qt::WA_AlwaysStackOnTop);
    ui->quickWidget->setClearColor(QColor(Qt::transparent));

}

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

void Dashboard::getValue(QString value)
{
    ui->quickWidget->rootContext()->setContextProperty("str_value", value);  // 向qml传递数据
}

.h文件

#ifndef DASHBOARD_H
#define DASHBOARD_H

#include <QWidget>

namespace Ui {
class Dashboard;
}

class Dashboard : public QWidget
{
    Q_OBJECT

public:
    explicit Dashboard(QWidget *parent = nullptr);
    ~Dashboard();
    void getValue(QString value);

private:
    Ui::Dashboard *ui;
};

#endif // DASHBOARD_H

.qml文件

import QtQuick 2.5
import QtQuick.Controls 2.12
import QtQuick.Window 2.10

Rectangle{
    id:control;
    color: Qt.rgba(0,0,0,0);
    property real radius: control.width > control.height ? control.height/2-10 : control.width/2-10;
    property real currenValue: str_value
    onCurrenValueChanged: {
        canvas.requestPaint()
    }

    Canvas{
        id:canvas
        antialiasing: true
        anchors.fill: parent
        width: parent.width
        height: parent.height
        onPaint: {
            var ctx = getContext("2d")
            ctx.reset();
            ctx.lineWidth = 3;
            ctx.strokeStyle = "white";
            ctx.fillStyle = "white";
            ctx.font = "20px 黑体";
            ctx.lineCap = "round"
            ctx.translate(width/2, height/2);

            // 绘制外圆
            ctx.save();
            ctx.beginPath();
            ctx.arc(0,0,control.radius,0,Math.PI*2,true)
            ctx.closePath();
            ctx.fill();
            ctx.stroke();
            ctx.restore();

            // 绘制故障区域
            ctx.save();
            ctx.strokeStyle = "#FF0000";
            ctx.fillStyle = "#FF0000";
            ctx.beginPath();
            ctx.moveTo(0,0);
            ctx.arc(0,0,control.radius,-60*Math.PI/180,-240*Math.PI/180,true);
            ctx.closePath();
            ctx.fill();
            ctx.stroke();

            // 绘制临界区域
            ctx.save();
            ctx.strokeStyle = "#FFA500";
            ctx.fillStyle = "#FFA500";
            ctx.beginPath();
            ctx.moveTo(0,0);
            ctx.arc(0,0,control.radius,0*Math.PI/180,-60*Math.PI/180,true);
            ctx.closePath();
            ctx.fill();
            ctx.stroke();

             // 绘制警告区域
            ctx.save();
            ctx.strokeStyle = "#FFFF00";
            ctx.fillStyle = "#FFFF00";
            ctx.beginPath();
            ctx.moveTo(0,0);
            ctx.arc(0,0,control.radius,30*Math.PI/180,360*Math.PI/180,true);
            ctx.closePath();
            ctx.fill();
            ctx.stroke();

            // 绘制正常区域
            ctx.save();
            ctx.strokeStyle = "#66FF33";
            ctx.fillStyle = "#66FF33";
            ctx.beginPath();
            ctx.moveTo(0,0);
            ctx.arc(0,0,control.radius,60*Math.PI/180,30*Math.PI/180,true);
            ctx.closePath();
            ctx.fill();
            ctx.stroke();

            // 绘制覆盖区域
            ctx.save();
            ctx.strokeStyle = "#03123E";
            ctx.fillStyle = "#03123E";
            ctx.beginPath();
            ctx.moveTo(0,0);
            ctx.arc(0,0,control.radius -40,-60*Math.PI/180,300*Math.PI/180,true);
            ctx.closePath();
            ctx.fill();
            ctx.stroke();
            ctx.restore()


            // 绘制刻度
            ctx.save();
            ctx.lineWidth = 2
            ctx.strokeStyle = "blue";
            ctx.fillStyle = "blue";
            ctx.rotate(Math.PI/6);
            ctx.beginPath()
            for(var i = 0; i <= 100/2;i++){
                if(i%5 == 0){
                    ctx.moveTo(0, control.radius)
                    ctx.lineTo(0, control.radius-15)
                    ctx.save()
                    ctx.translate(0, control.radius -25)
                    ctx.fillText(String(i*2),0,0)
                    ctx.restore()
                }
                else{
                    ctx.moveTo(0,control.radius)
                    ctx.lineTo(0, control.radius-5)

                }
                ctx.rotate((Math.PI*2-Math.PI/3)/100*2)
            }
            ctx.stroke()
            ctx.restore()

            // 绘制内圆
            ctx.save();
            ctx.strokeStyle = "grey";
            ctx.fillStyle = "grey";
            ctx.beginPath()
            ctx.arc(0,0,15,0,Math.PI*2,true)
            ctx.fill();
            ctx.stroke();
            ctx.restore();


            // 绘制指针
            ctx.save()
            ctx.strokeStyle = "purple"
            ctx.fillStyle = "purple"
            ctx.rotate(Math.PI/6)
            ctx.rotate(((Math.PI*2 - Math.PI/3)/100*2) * (control.currenValue/2));
            ctx.beginPath()
            ctx.lineTo(0,0)
            ctx.lineTo(8,20)
            ctx.lineTo(0, control.radius-35)
            ctx.lineTo(-8,20)
            ctx.closePath()
            ctx.fill()
            ctx.stroke()
            ctx.restore()

            ctx.save()
            ctx.strokeStyle = "transparent"
            ctx.fillStyle = "white"
            ctx.font = "18px 黑体"
            ctx.fillText("评估得分:"+ String(currenValue),-50,control.radius/2)
            ctx.stroke()
            ctx.restore()
        }
    }
}

运行结果:

 

posted on 2021-09-23 11:25  缘随风烬  阅读(1865)  评论(0编辑  收藏  举报