目录
一、绘制两圆上箭头,即从两圆心连线与圆上的交点画箭头。
首先得到根据圆心得到圆上坐标
再根据圆上坐标画出箭头
二、上代码
/*
* 首先根据圆心求出两点间距离l
* r/l根据等比三角形求出圆心连线在圆上的点坐标(有兴趣可以画图分析)
*/
void cutLineLength(QPoint p1,QPoint p2,QPoint &p3,QPoint &p4,int r)
{
double dDist=0,dDeta=0;
double dPX,dPY,dP1X,dP1Y,dP2X,dP2Y;
dPX = p1.x() - p2.x();
dPY = p1.y() - p2.y();
dDist = sqrt(dPX*dPX +dPY*dPY);
dDeta = r / dDist;
dP1X = p1.x() - (dPX)*dDeta;
dP1Y = p1.y() - (dPY)*dDeta;
dP2X = p2.x() + dPX*dDeta;
dP2Y = p2.y() + dPY*dDeta;
p3.setX(dP1X);
p3.setY(dP1Y);
p4.setX(dP2X);
p4.setY(dP2Y);
}
//说白了箭头就是四个点组成的。上面的函数得到了两个圆上坐标,
//选取其中一个点作为箭头点(这里的p2)得到p2两边的坐标p3,p4。
void calArrowPoint(QPoint p1,QPoint p2,QPoint& p3,QPoint& p4)
{
double arrowLength = 10;
double arrowDegrees = 0.5;
//求p1和p2之间的角度
double angle = atan2(p2.y()-p1.y(),p2.x()-p1.x());
p3.setX(p2.x() - arrowLength * cos(angle - arrowDegrees));
p3.setY(p2.y() - arrowLength * sin(angle - arrowDegrees));
p4.setX(p2.x() - arrowLength * cos(angle + arrowDegrees));
p4.setY(p2.y() - arrowLength * sin(angle + arrowDegrees));
}
三、在QT中画出这两个圆和箭头
在头文件中重在paintEvent函数和两个点坐标,并实现重绘。
.h
protected:
void paintEvent(QPaintEvent *event) override;
private:
QPoint fastPoint;
QPoint lastPoint;
int r = 50;
.cpp
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QString str = "hello world";
QString drawStr;
if(str.length() > 3)
{
drawStr = str.mid(0,2);
drawStr.append("...");
}
QFont font;
painter.save();
font = painter.font();
font.setPointSize(12);
painter.setFont(font);
painter.setBrush(QBrush(QColor(200,200,100)));
painter.drawEllipse(fastPoint,r,r);//原点为fastPoint,半径为50
painter.drawEllipse(lastPoint,r,r);
painter.drawText(fastPoint.x()-r,fastPoint.y()-r,2*r,2*r,
Qt::AlignHCenter | Qt::AlignVCenter,str);
//painter.drawLine(fastPoint,lastPoint);
painter.restore();
QPoint p1,p2,p3,p4;
cutLineLength(fastPoint,lastPoint,p1,p2,r/2);
calArrowPoint(p1,p2,p3,p4);
painter.drawLine(p1,p2);
painter.drawLine(p2,p3);
painter.drawLine(p2,p4);
}
到这里就可以画出来两个圆和箭头了
四、实现移动这个带文字的圆并且箭头跟随
.h 增加鼠标按下、移动、释放事件
protected:
void mouseMoveEvent(QMouseEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void paintEvent(QPaintEvent *event) override;
private:
Ui::MainWindow *ui;
bool pushButton = false;
QPoint fastPoint;
QPoint lastPoint;
QPoint movePoint;
int r = 50;
.cpp 中处理事件
//鼠标移动事件
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
QPoint p = event->pos();
if(pushButton)
{
fastPoint.setX(p.x() + movePoint.x());
fastPoint.setY(p.y() + movePoint.y());
update();
}
}
//鼠标按下
void MainWindow::mousePressEvent(QMouseEvent *event)
{
QPoint p = event->pos();
if(event->button() == Qt::LeftButton && p.x() > fastPoint.x()-r/2 &&
p.x() <fastPoint.x()+r/2 && p.y() > fastPoint.y() -r/2
&& p.y() < fastPoint.y() + r/2)
{
pushButton = true;
movePoint.setX(fastPoint.x() - p.x());
movePoint.setY(fastPoint.y() - p.y());
}
}
//鼠标释放
void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton)
pushButton = false;
}
五、源码
.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTimer>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
protected:
void mouseMoveEvent(QMouseEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void paintEvent(QPaintEvent *event) override;
private:
Ui::MainWindow *ui;
bool pushButton = false;
QPoint fastPoint;
QPoint lastPoint;
QPoint movePoint;
int r = 50;
};
#endif // MAINWINDOW_H
.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPainter>
#include <QDebug>
#include <QFile>
#include <QMouseEvent>
#include <math.h>
/*
* 画两个圆之间的箭头(圆上)
* 首先根据圆心求出两点间距离l
* r/l根据勾股定理求出圆心连线在圆上的点坐标(自己分析)
* 根据圆上坐标画箭头p3->p4
*/
void cutLineLength(QPoint p1,QPoint p2,QPoint &p3,QPoint &p4,int r)
{
double dDist=0,dDeta=0;
double dPX,dPY,dP1X,dP1Y,dP2X,dP2Y;
dPX = p1.x() - p2.x();
dPY = p1.y() - p2.y();
dDist = sqrt(dPX*dPX +dPY*dPY);
dDeta = r / dDist;
dP1X = p1.x() - (dPX)*dDeta;
dP1Y = p1.y() - (dPY)*dDeta;
dP2X = p2.x() + dPX*dDeta;
dP2Y = p2.y() + dPY*dDeta;
p3.setX(dP1X);
p3.setY(dP1Y);
p4.setX(dP2X);
p4.setY(dP2Y);
}
void calArrowPoint(QPoint p1,QPoint p2,QPoint& p3,QPoint& p4)
{
double arrowLength = 10;
double arrowDegrees = 0.5;
//求p1和p2之间的角度
double angle = atan2(p2.y()-p1.y(),p2.x()-p1.x());
p3.setX(p2.x() - arrowLength * cos(angle - arrowDegrees));
p3.setY(p2.y() - arrowLength * sin(angle - arrowDegrees));
p4.setX(p2.x() - arrowLength * cos(angle + arrowDegrees));
p4.setY(p2.y() - arrowLength * sin(angle + arrowDegrees));
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
fastPoint = QPoint(50,50);
lastPoint = QPoint(200,200);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QString str = "hello world";
QString drawStr;
if(str.length() > 3)
{
drawStr = str.mid(0,2);
drawStr.append("...");
}
painter.setRenderHint(QPainter::Antialiasing);
/*
* translate改变坐标系,将原点坐标改到屏幕中央
*side是窗口最小的那个边长
*200是缩放的比例,当side/200达到1、2、3...n时就会进行缩放
*也就是说当最小边长为200、400、600、800时会进行1、2、3、4倍的放大
*/
//int side = qMin(width(),height());
//painter.translate(width()/2,height()/2);
//painter.scale(side/ 200 , side / 200);
QFont font;
painter.save();
font = painter.font();
font.setPointSize(12);
painter.setFont(font);
painter.setBrush(QBrush(QColor(200,200,100)));
painter.drawEllipse(fastPoint,r/2,r/2);//原点为fastPoint,半径为50
painter.drawEllipse(lastPoint,r/2,r/2);
painter.drawText(fastPoint.x()-r/2,fastPoint.y()-r/2,r,r,
Qt::AlignHCenter | Qt::AlignVCenter,str);
//painter.drawLine(fastPoint,lastPoint);
painter.restore();
QPoint p1,p2,p3,p4;
cutLineLength(fastPoint,lastPoint,p1,p2,r/2);
calArrowPoint(p1,p2,p3,p4);
painter.drawLine(p1,p2);
painter.drawLine(p2,p3);
painter.drawLine(p2,p4);
}
//鼠标移动事件
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
QPoint p = event->pos();
if(pushButton)
{
fastPoint.setX(p.x() + movePoint.x());
fastPoint.setY(p.y() + movePoint.y());
update();
}
}
//鼠标按下
void MainWindow::mousePressEvent(QMouseEvent *event)
{
QPoint p = event->pos();
if(event->button() == Qt::LeftButton && p.x() > fastPoint.x()-r/2 &&
p.x() <fastPoint.x()+r/2 && p.y() > fastPoint.y() -r/2
&& p.y() < fastPoint.y() + r/2)
{
pushButton = true;
movePoint.setX(fastPoint.x() - p.x());
movePoint.setY(fastPoint.y() - p.y());
}
}
//鼠标释放
void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton)
pushButton = false;
}