zl程序教程

您现在的位置是:首页 >  工具

当前栏目

Qt之实现摇杆功能

Qt 实现 功能
2023-09-27 14:29:14 时间

实现效果


程序

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QDialog>
#include <QInputDialog>
#include <QMessageBox>
#include <QDebug>
#include <QPainter>
#include <QPaintEvent>
#include <QMouseEvent>

#define SMALL_CIRCLE_RADIUS 30 //小圆半径 (小圆图片分辨率为60*60)
#define BIG_CIRCLE_RADIUS 90 //大圆半径 (大圆图片分辨率为180*180)

class Widget : public QDialog
{
    Q_OBJECT

public:
    Widget(QDialog *parent = nullptr);
    ~Widget();

private:
    QPoint BigCir_xy; //大圆圆心坐标
    QPoint SmallCir_xy; //小圆圆心坐标

    bool MousePressFlag; //鼠标按下的标志位

    QPoint MapRemov_Old;

    void Init();

    void paintEvent(QPaintEvent *event); //绘图事件:绘制地图、摇杆中的大圆和小圆
    void mouseMoveEvent(QMouseEvent *); //鼠标移动事件:实现摇杆功能
    void mousePressEvent(QMouseEvent *); //鼠标按下事件:获取摇杆所在的实时坐标
    void mouseReleaseEvent(QMouseEvent *); //鼠标释放事件:释放鼠标,则MousePressFlag复位,且小圆圆心设置为初始值,更新绘图事件后,重新绘图使小圆(摇杆)回到原处
};

#endif // WIDGET_H


widget.cpp

#include "widget.h"

Widget::Widget(QDialog *parent)
    : QDialog(parent)
{
    Init(); //初始化函数
}

Widget::~Widget()
{

}

//初始化函数
void Widget::Init()
{
    //设置窗口无边框且窗口显示在最顶层
    //this->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::WindowStaysOnTopHint);

    //设置大圆圆心位置
    SmallCir_xy.setX(300);
    SmallCir_xy.setY(300);
    //设置小圆圆心位置,与大圆相同
    BigCir_xy=SmallCir_xy;

    //设置窗口固定大小为400*400
    this->setFixedSize(400,400);

    //鼠标点击标志初始化
    MousePressFlag=false;
}

//绘图事件:绘制地图、摇杆中的大圆和小圆
void Widget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    //绘图画笔
    QPainter painter(this);
    //抗锯齿
    painter.setRenderHint(QPainter::Antialiasing, true);
    //消锯齿
    painter.setRenderHints(QPainter::SmoothPixmapTransform);

    //绘制摇杆中的大圆
    QPixmap bigCircle_Pixmap;
    bigCircle_Pixmap.load(":/new/prefix1/image/max.png");
    painter.drawPixmap(SmallCir_xy.x()-BIG_CIRCLE_RADIUS,SmallCir_xy.y()-BIG_CIRCLE_RADIUS,\
                       BIG_CIRCLE_RADIUS*2,BIG_CIRCLE_RADIUS*2,bigCircle_Pixmap);

    //绘制摇杆中的小圆
    QPixmap smallCircle_Pixmap;
    smallCircle_Pixmap.load(":/new/prefix1/image/min.png");
    painter.drawPixmap(BigCir_xy.x()-SMALL_CIRCLE_RADIUS,BigCir_xy.y()-SMALL_CIRCLE_RADIUS,\
                       SMALL_CIRCLE_RADIUS*2,SMALL_CIRCLE_RADIUS*2,smallCircle_Pixmap);
}

//鼠标移动事件:实现摇杆功能
void Widget::mouseMoveEvent(QMouseEvent *e)
{
    QPoint rocker_xy; //摇杆所在的实时坐标
    QByteArray xy;
    xy.resize(2);
    int x,y;
    rocker_xy=e->pos();

    if(MousePressFlag) //MousePressFlag为true,说明鼠标点击在了大圆内,才进行计算
    {
        //小圆圆心出了大圆则在大圆上90-25=65  65*65=4225
        if(pow((rocker_xy.x()-SmallCir_xy.x()),2)+pow((rocker_xy.y()-SmallCir_xy.y()),2)>8100)
        {
            x=int( 90*cos(atan2(abs(rocker_xy.y()-SmallCir_xy.y()),abs(rocker_xy.x()-SmallCir_xy.x()))) );
            y=int( 90*sin(atan2(abs(rocker_xy.y()-SmallCir_xy.y()),abs(rocker_xy.x()-SmallCir_xy.x()))) );

            //第一象限
            if(rocker_xy.x()>SmallCir_xy.x()&&rocker_xy.y()>SmallCir_xy.y())
            {
                BigCir_xy.setX(x+SmallCir_xy.x());
                BigCir_xy.setY(y+SmallCir_xy.y());
            }
            //第二象限
            else if(rocker_xy.x()<SmallCir_xy.x()&&rocker_xy.y()>SmallCir_xy.y())
            {
                BigCir_xy.setX(-x+SmallCir_xy.x());
                BigCir_xy.setY(y+SmallCir_xy.y());
                x=-x;
            }
            //第三象限
            else if(rocker_xy.x()<SmallCir_xy.x()&&rocker_xy.y()<SmallCir_xy.y())
            {
                BigCir_xy.setX(-x+SmallCir_xy.x());
                BigCir_xy.setY(-y+SmallCir_xy.y());
                x=-x;
                y=-y;
            }
            //第四象限
            else if(rocker_xy.x()>SmallCir_xy.x()&&rocker_xy.y()<SmallCir_xy.y())
            {
                BigCir_xy.setX(x+SmallCir_xy.x());
                BigCir_xy.setY(-y+SmallCir_xy.y());
                y=-y;
            }
        }
        else
        {
            BigCir_xy=rocker_xy;
            x=rocker_xy.x()-SmallCir_xy.x();
            y=rocker_xy.y()-SmallCir_xy.y();
        }
        xy[0]=char( x );
        xy[1]=char( y );
        //hex发送
        //mycartcp->TCPSend(xy);
        qDebug()<<x<<y;
        update();
    }

    MapRemov_Old=rocker_xy;
}

//鼠标释放事件:释放鼠标,则MousePressFlag复位,且小圆圆心设置为初始值,更新绘图事件后,重新绘图使小圆(摇杆)回到原处
void Widget::mouseReleaseEvent(QMouseEvent *e)
{
    Q_UNUSED(e);

    //释放鼠标,则MousePressFlag复位
    MousePressFlag=false;
    //小圆圆心设置为初始值,即大圆圆心值
    BigCir_xy.setX(SmallCir_xy.x());
    BigCir_xy.setY(SmallCir_xy.y());

    this->update(); //更新绘图事件后,重新绘图使小圆(摇杆)回到原处
}

//鼠标按下事件:获取摇杆所在的实时坐标
void Widget::mousePressEvent(QMouseEvent *e)
{
    QPoint rocker_xy; //摇杆所在的实时坐标

    rocker_xy=e->pos(); //获取摇杆所在的实时坐标
    qDebug() <<"摇杆坐标: " <<rocker_xy;

    //鼠标点击,在大圆内才设置MousePressFlag
    if(pow((rocker_xy.x()-SmallCir_xy.x()),2)+pow((rocker_xy.y()-SmallCir_xy.y()),2)<=8100) //判断摇杆是否在大圆内
    {
       MousePressFlag=true;
    }
    else
    {
       MapRemov_Old=rocker_xy;
    }
}