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安装教程。

原创粉丝点击