欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Qt 模拟安卓虚拟摇杆实现

程序员文章站 2024-02-11 11:18:34
...
#include "handle.h"

Handle::Handle(QWidget *parent)
    : QWidget(parent)
{
    setAutoFillBackground(true);
    setPalette(QPalette(Qt::white));
    resize(200,200);
    setMinimumSize(100,100);
    mouseX=width()/2;
    mouseY=height()/2;
    tim=new QTimer(this);
    connect(tim,&QTimer::timeout,this,[=]{
       emit keyNumchanged(getKeyNum());
   });
    connect(this,&Handle::keyNumchanged,this,[=](int num){
        qDebug()<<num<<endl;
    });
}

Handle::~Handle()
{

}
void Handle::paintEvent(QPaintEvent *){

    QPainter painter(this);

    int side = qMin(width(), height());

    padR=side/2; //底盘半径
    padX=padR;//底盘圆心
    padY=padR;//底盘圆心
    handleR=padR/4;//摇杆圆半径
    int handleMaxR=padR-handleR;
    QColor handleColor(Qt::gray);
    //加载底盘图像
    painter.save();

    painter.scale(side / 400.0, side / 400.0);//坐标会随窗口缩放
    painter.drawPixmap(0, 0, QPixmap(":/image/pad.png"));
    painter.restore();

    //自绘底盘
//    painter.save();
//    QRadialGradient RadialGradient(padR,padR,padR*3,padR,padR);//圆心2,半径1,焦点2
//    RadialGradient.setColorAt(0,QColor(90,90,90,127));//渐变
//    RadialGradient.setColorAt(1,QColor(255,255,255,190));//渐变
//    painter.setBrush(RadialGradient);
//    painter.setPen(Qt::NoPen);
//    painter.drawEllipse(QPoint(padR,padR),side/2,side/2);//大圆盘
//    painter.restore();

 //   painter.drawText(20,20,tr("%1,%2,%3").arg(mouseX).arg(mouseY).arg(handPaddis));

    if(!mousePressed){//鼠标没按下则摇杆恢复到底盘中心
        mouseX=padX;
        mouseY=padY;
    }
    handPadDis=Pointdis(padR,padR,mouseX,mouseY);
    if(handPadDis<=handleMaxR){
        handleX=mouseX;
        handleY=mouseY;
    }
    else {
        handleX=(int)(handleMaxR*(mouseX-padX)/handPadDis+padX);
        handleY=(int)(handleMaxR*(mouseY-padY)/handPadDis+padY);
    }
   // painter.drawText(200,200,tr("%1,%2,%3").arg(handleX).arg(handleY).arg(handPaddis));
    painter.setPen(Qt::NoPen);
    painter.setBrush(handleColor);
    painter.drawEllipse(QPoint(handleX,handleY),handleR,handleR);//摇杆
}
void Handle::mouseMoveEvent(QMouseEvent* event){
    static bool r=false;
    mouseX=event->pos().x();
    mouseY=event->pos().y();
    if(r==true){
       update();
       r=false;
    }
    else{
        r=true;
    }
}
void Handle::mouseReleaseEvent(QMouseEvent* event){
    mouseX=width()/2;
    mouseY=height()/2;
    tim->stop();
    mousePressed=false;
    emit keyNumchanged(Handle::stop);
    update();
}
void Handle::mousePressEvent(QMouseEvent* event){
    mouseX=event->pos().x();
    mouseY=event->pos().y();
    tim->start(100);
    mousePressed=true;
    update();
}

double Handle::Pointdis(int a,int b,int x,int y){
    return sqrt((double)((x-a)*(x-a)+(y-b)*(y-b)));
}
int Handle::getKeyNum(){
    int x,y;
    int keynum;
    x=(int)(handleX*3.0/(padR*2));
    y=(int)(handleY*3.0/(padR*2));
    keynum=3*y+x;
    return keynum;
}
#ifndef HANDLE_H
#define HANDLE_H

#include <QWidget>
#include <QPainter>
#include <QDrag>
#include <QMouseEvent>
#include <QtMath>
#include <QTimer>
#include <QDebug>
class Handle : public QWidget
{
    Q_OBJECT

public:
    Handle(QWidget *parent = 0);
    ~Handle();
    enum {upleft=0,up,upright,left,stop,right,downleft,down,downright};
signals:
    void keyNumchanged(int num);
protected:
    void paintEvent(QPaintEvent *event)override;
    void mouseMoveEvent(QMouseEvent *event)override;
    void mouseReleaseEvent(QMouseEvent *event)override;
    void mousePressEvent(QMouseEvent *event)override;
  //  void resizeEvent(QResizeEvent *event)override;
private:
    int mouseX;
    int mouseY;
  int handleX;//摇杆
  int handleY;
  int handleR;
  int padX;//底盘
  int padY;
  int padR;
  double handPadDis;//两圆圆心距离
  bool mousePressed;
  QTimer *tim;
private:
   double Pointdis(int a,int b,int x,int y);//两点距离
   int getKeyNum();

};

#endif // HANDLE_H

实现功能:

       1.实现摇杆在圆盘内任意位置移动,鼠标超出圆盘则停靠在圆盘边界

       2.鼠标按下时每100ms发送一次键值,键值定义为

       enum {upleft=0,up,upright,left,stop,right,downleft,down,downright};

预览:

Qt 模拟安卓虚拟摇杆实现

工程文件:

#-------------------------------------------------
#
# Project created by QtCreator 2019-10-14T21:24:47
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = handle
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

CONFIG += c++11

SOURCES += \
        main.cpp \
        handle.cpp

HEADERS += \
        handle.h

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

RESOURCES += \
    pic.qrc

注意必须加:

CONFIG += c++11