Qt与Qml交互的小Demo
来源:互联网 发布:能以礼让为国乎 编辑:程序博客网 时间:2024/06/04 18:19
目录
- 目录
- 1控制界面
- 2Qml与C交互
- 3Qml直升机三维显示
- 主函数
这是我第一次写博客,想把自己做的东西写出来与大家分享,同时欢迎大家批评指正。
1、控制界面
控制界面借了qwt,以及一些简单的Qt鼠标事件,先上效果图,有图有真相。
其中大圆表示虚拟摇杆,可控制飞机姿态,条形表盘为Qwt所做显示姿态角,滑块表示直升机油门。cpp代码如下:
#include "control.h"#include "ui_control.h"#include <qdebug.h>#include <qwt_color_map.h>Control::Control(QWidget *parent) : QDialog(parent), ui(new Ui::Control){ helicopter=new Helicopter(this); ui->setupUi(this); QwtLinearColorMap *DirectionThermo_1map = new QwtLinearColorMap(); DirectionThermo_1map->setColorInterval( Qt::blue, Qt::red ); ui->Thermo_3->setColorMap( DirectionThermo_1map ); ui->Thermo->setOriginMode( QwtThermo::OriginCustom ); ui->Thermo->setOrigin( 0.0 ); ui->Thermo_2->setOriginMode( QwtThermo::OriginCustom ); ui->Thermo_2->setOrigin( 0.0 ); connect(ui->verticalSlider,SIGNAL(valueChanged(int)),this,SLOT(SetThrottle()));}Control::~Control(){ delete ui;}//===================================鼠标移动信息获取,虚拟手柄===================================void Control::mouseMoveEvent(QMouseEvent *event){ Mouse_Pos = event->pos(); MouseX=Mouse_Pos.x(); MouseY=Mouse_Pos.y(); Dis = sqrt(double(pow(MouseX -110,2) + pow(MouseY -110,2))); RelativeX=MouseX-110; RelativeY=MouseY-110; if(Dis<=100){ ui->label->move(MouseX-30,MouseY-30); }else if(Dis<=150){ Ratio=100/Dis; ui->label->move(RelativeX*Ratio+80,RelativeY*Ratio+80); } //qDebug()<<Mouse_Pos.x()<<"|"<<Mouse_Pos.y(); ui->Thermo->setValue(-RelativeX); ui->Thermo_2->setValue(RelativeY); emit helicopter->receiveRotation(RelativeX,RelativeY);}void Control::mouseReleaseEvent(QMouseEvent *event){ ui->label->move(80,80); RelativeX=RelativeY=0; ui->Thermo->setValue(RelativeY); ui->Thermo_2->setValue(RelativeX); emit helicopter->receiveRotation(RelativeX,RelativeY);}void Control::SetThrottle(){ Throttle=ui->verticalSlider->value(); ui->Thermo_3->setValue(Throttle); emit helicopter->receiveThrottle(Throttle);}
通过鼠标事件获取鼠标位置,并使黑型按钮运动至鼠标位置,最后将RelativeX,RelativeY,Throttle传入到Helicopter类。
2、Qml与C++交互
二话不说直接上代码:
.h文件
#ifndef HELICOPTER_H#define HELICOPTER_H#include <QObject>class Helicopter : public QObject{ Q_OBJECTpublic: explicit Helicopter(QObject *parent = 0);signals: void sendRotation(const double&mMouseX, const double&mMouseY); void sendThrottle(const double&mThrottle);public slots: void receiveRotation(double, double); void receiveThrottle(double);protected: void timerEvent( QTimerEvent *e );};#endif // HELICOPTER_H
.cpp文件
#include "helicopter.h"#include <QDebug>static double MouseX;static double MouseY;static double Throttle;static double mmmm;Helicopter::Helicopter(QObject *parent) : QObject(parent){ startTimer(5);}void Helicopter::timerEvent(QTimerEvent *e){ emit sendRotation(MouseX,MouseY); mmmm+=Throttle/5; if(mmmm>360) { mmmm-=360; } emit sendThrottle(mmmm);}void Helicopter::receiveRotation(double XX, double YY){ MouseX=XX; MouseY=YY;}void Helicopter::receiveThrottle(double Thro){ Throttle = Thro;}
将控制面板的值传入到几个静态全局变量中,通过定时器传输至Qml。这里需要注意:信号第一位需要小写,然后Qml中调用时则需要大写!类的首字母也需要大写。
3、Qml直升机三维显示
main.qml代码如下:
import QtControl 1.0//import QtQuick 2.0import QtQuick 2.7import QtQuick.Scene3D 2.0import QtQuick.Controls 2.0Item { id:item property real xratation: 0.0 property real yratation: 0.0 property real zratation: 0.0 property real throttle: 0.0 property real fly: 0.0 Hem{ id:mmmm onSendRotation:{ xratation=-mMouseX yratation=mMouseY } onSendThrottle:{ throttle=mThrottle fly=throttle } } Text { text: yratation anchors.top: parent.top anchors.topMargin: 10 anchors.horizontalCenter: parent.horizontalCenter MouseArea { anchors.fill: parent onClicked:yratation+=10 } } Text { text: yratation anchors.bottom: parent.bottom anchors.bottomMargin: 10 anchors.horizontalCenter: parent.horizontalCenter MouseArea { anchors.fill: parent onClicked: yratation-=10//scene3d.multisample = !scene3d.multisample } } Text { text: xratation anchors.left: parent.left anchors.leftMargin: 10 anchors.verticalCenter: parent.verticalCenter MouseArea { anchors.fill: parent onClicked:xratation+=10//animation.start() } } Text { text: xratation anchors.right: parent.right anchors.rightMargin: 10 anchors.verticalCenter: parent.verticalCenter MouseArea { anchors.fill: parent onClicked: xratation-=10//animation.stop()//scene3d.multisample = !scene3d.multisample } } Rectangle { id: scene anchors.fill: parent anchors.margins: 50 color: "darkRed" transform: Rotation { id: sceneRotation axis.x: 1 axis.y: 0 axis.z: 0 origin.x: scene.width / 2 origin.y: scene.height / 2 } MouseArea { anchors.fill: parent onWheel: { wheel.angleDelta.y / 100.0 } onPositionChanged:{ } } Scene3D { id: scene3d anchors.fill: parent anchors.margins: 10 focus: true aspects: ["input", "logic"] cameraAspectRatioMode: Scene3D.AutomaticAspectRatio Show {xrotation:xratation yrotation:yratation mfly:fly } } }}
直升机模型则建立层级关系,第一层包括:三维坐标环、直升机整机,主要是为了添加坐标环而存在。代码如下:
import QtQuick 2.1 as QQ2import Qt3D.Core 2.0import Qt3D.Render 2.0import Qt3D.Input 2.0import Qt3D.Extras 2.0Entity { id: root property real xrotation: 0.0 property real yrotation: 0.0 property real zrotation: 0.0 property real mfly: 0.0 // Render from the mainCamera components: [ RenderSettings { activeFrameGraph: ForwardRenderer { id: renderer camera: mainCamera } }, // Event Source will be set by the Qt3DQuickWindow InputSettings { }, DirectionalLight { worldDirection: Qt.vector3d(2, 2, -3).normalized(); color: "#fbf9ce" intensity: 0.4 } ] BasicCamera { id: mainCamera position: Qt.vector3d( -60, 0, 0 ) } //FirstPersonCameraController { camera: mainCamera } OrbitCameraController { camera: mainCamera} WireframeMaterial { id: xaxisM effect: WireframeEffect {} ambient: Qt.rgba( 1.0, 0.0, 0.0, 1.0 ) diffuse: Qt.rgba( 1.0, 0.0, 0.0, 1.0 ) } WireframeMaterial { id: yaxisM effect: WireframeEffect {} ambient: Qt.rgba( 0.0, 1.0, 0.0, 1.0 ) diffuse: Qt.rgba( 0.0, 1.0, 0.0, 1.0 ) } WireframeMaterial { id: zaxisM effect: WireframeEffect {} ambient: Qt.rgba( 0.0, 0.0, 1.0, 1.0 ) diffuse: Qt.rgba( 0.0, 0.0, 1.0, 1.0 ) } Xaxis { id: xaxis material: xaxisM } Yaxis { id: yaxis material: yaxisM } Zaxis { id: zaxis material: zaxisM } Helicopter{ id:helicopter mxrotation: xrotation myrotation: yrotation mzrotation: zrotation hfly: mfly }}
第二层包括:主桨、副桨、机身,负责控制整机的姿态运动。代码如下:
import QtQuick 2.1 as QQ2import Qt3D.Core 2.0import Qt3D.Render 2.0import Qt3D.Input 2.0import Qt3D.Extras 2.0Entity { id: root property real mxrotation: 0.0 property real myrotation: 0.0 property real mzrotation: 0.0 property real hfly: 0.0 // Render from the mainCamera components: [ Transform { id: helicopterT translation: Qt.vector3d(0, 0, 0) rotation: fromEulerAngles(mxrotation, myrotation, mzrotation) } ] WireframeMaterial { id: wireframeMaterial effect: WireframeEffect {} ambient: Qt.rgba( 0.25, 0.25, 0.4, 1.0 ) diffuse: Qt.rgba( 0.4, 0.4, 0.8, 1.0 ) specular: Qt.rgba( 0.4, 0.4, 0.8, 1.0 ) shininess: 100 } WireframeMaterial { id: airscrewMaterial effect: WireframeEffect {} ambient: Qt.rgba( 0.2, 0.4, 0.2, 1.0 ) diffuse: Qt.rgba( 0.3, 0.7, 0.3, 1.0 ) specular: Qt.rgba( 0.3, 0.7, 0.3, 1.0 ) shininess: 150 } TrefoilKnot{ id: trefoilknot material: wireframeMaterial } Airscrew{ id: airscrew material: airscrewMaterial arfa:hfly } Empennage{ id:empennage efly: hfly }}
第三层主要由三个文件构成:分别负责主桨自转与模型添加、副桨偏移、机身的模型添加。其中副桨代码:
import QtQuick 2.1 as QQ2import Qt3D.Core 2.0import Qt3D.Render 2.0import Qt3D.Input 2.0import Qt3D.Extras 2.0Entity { id: root property real efly: 0.0 // Render from the mainCamera components: [ Transform { id: helicopterE translation: Qt.vector3d(-10.64495,0.276468,-0.1446) } ] WireframeMaterial { id: airscrewMaterial effect: WireframeEffect {} ambient: Qt.rgba( 0.4, 0.2, 0.2, 1.0 ) diffuse: Qt.rgba( 0.4, 0.2, 0.2, 1.0 ) specular: Qt.rgba( 0.4, 0.2, 0.2, 1.0 ) shininess: 150 } Airscrewf{ id: airscrewf material: airscrewMaterial phi:5*efly }}
最后一层也是最后一部分啦,负责副桨自转,代码我就不贴了大同小异。最后Qml运行界面如下:
4、主函数
直接上代码:
#include <Qt3DQuickExtras/qt3dquickwindow.h>#include <Qt3DQuick/QQmlAspectEngine>#include <QGuiApplication>#include <QtQml>#include <QQuickView>#include "control.h"#include <QApplication>#include "helicopter.h"int main(int argc, char* argv[]){ QApplication app(argc, argv); //QGuiApplication app(argc, argv); qmlRegisterType<Helicopter>("QtControl",1,0,"Hem"); QQuickView view; view.resize(500, 500); view.setResizeMode(QQuickView::SizeRootObjectToView); view.setSource(QUrl("qrc:///main.qml")); //view.setFlags(Qt::FramelessWindowHint); view.show(); Control zmx; zmx.show(); return app.exec();}
主要通过qmlRegisterType(“QtControl”,1,0,”Hem”);将Helicopter类注册到Qt元对象系统。这里相关Qml与C++交互我就不多说了,网上有好多。
这里有几个我认为讲的不错的帖子:
http://blog.csdn.net/foruok/article/details/32698603#
http://www.cnblogs.com/findumars/p/6090850.html
最后不对的地方也请大家批评指正,共同进步。
源代码下载链接:
http://download.csdn.net/download/zmxzmx110/10040302
用Qt5.7.0,如果不想安装Qwt可屏蔽相关代码也能运行。过几天我会列出详细的Qwt安装教程。
- Qt与Qml交互的小Demo
- qml与C++交互传值的简单demo
- Qt移动应用开发:QML与C++的交互
- Qt移动应用开发:QML与Java的交互
- Android 与H5交互的小Demo
- QML与C++的交互
- qml与C++的交互
- QML, Qt C++混合编程--QML与Qt C++ 交互机制探讨与总结
- QML与Qt C++ 交互机制探讨与总结
- QML与Qt C++ 交互机制探讨与总结
- QML与Qt C++ 交互机制探讨与总结
- QML与Qt C++ 交互机制探讨与总结
- QML与Qt C++ 交互机制探讨与总结
- QML与Qt C++ 交互机制探讨与总结
- 一个lua 与c交互的小demo
- Qt移动应用开发(六):QML与C++的交互
- Qt移动应用开发(七):QML与Java的交互
- Qt移动应用开发(七):QML与Java的交互
- Java基本数据类型的最大值和最小值
- Solr使用DataImportHandler(DIH)工具加载结构化数据
- JS如何判断一个对象为空
- jmeter详细信息输出以及图形化查看
- Maven学习之路三(Maven的目录结构)
- Qt与Qml交互的小Demo
- Impala Shell 和 Impala SQL
- Bean基本概念
- 【STM8L】STM8L之红外发射(定时器中断产生38K信号)
- HTTP 状态码
- yum install mysql5.x
- Oracle导入包含clob字段的dmp文件报错问题解决办法
- checkbox的回显, 打上对勾却无法保存到后台用模拟点击解决 ,等问题总结angluarjs
- 一个手咪按键,检测抬起和按下的思考