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() } } }
运行结果: