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};
预览:
工程文件:
#-------------------------------------------------
#
# 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