<pre style="margin-top: 0px; margin-bottom: 0px;"><span style="font-family: Arial, Helvetica, sans-serif;">这篇文章实现了将QPainter和(painEvent,mouseEvent)的结合使用</span>
窗口中平行四边形可以通过鼠标任意的调整大小,通过QSolider任意的改变四边形的角度;
不多说了亮代码:
<pre name="code" class="cpp">#include "calculate.h"
#include <QLine>
Calculate::Calculate(Input_T *data,QObject *parent) : m_Input_data(*data),QObject(parent)
{
}
Calculate::Output_T *Calculate::Result(Input_T *m_Input_data1)
{
float k=tanf(m_Input_data1->Angle_offset/180*PI);
QPointF O2=m_Input_data1->pos_O;
O2*=2;
m_Output_data.point[0]=m_Input_data1->pos_A;
m_Output_data.point[2]=O2-m_Output_data.point[0];
float Xa=m_Input_data1->pos_A.x();
float Ya=m_Input_data1->pos_A.y();
float Xo=m_Input_data1->pos_O.x();
float Yo=m_Input_data1->pos_O.y();
float Xb=(2*Ya+k*Xa-2*(Yo+k*Xo))/(-k);
float Yb=Ya;
m_Output_data.point[1]=QPointF(Xb,Yb);
m_Output_data.point[3]=O2-m_Output_data.point[1];
return &m_Output_data;
}
#ifndef CALCULATE_H
#define CALCULATE_H
const double PI=3.1415926;
#include <QObject>
#include <QPointF>
class Calculate : public QObject
{
Q_OBJECT
public:
struct Input_T
{
QPointF pos_O;
QPointF pos_A;
float Angle_offset;
int W;
int H;
};
struct Output_T
{
QPointF point[4];
QPointF pos_start;
QPointF pos_end;
float Angle_offset;
QPointF pos_A;
QPointF pos_B;
};
explicit Calculate(Input_T *data=NULL,QObject *parent = 0);
public:
Output_T *Result(Input_T *m_Input_data1);
private:
Input_T m_Input_data;
Output_T m_Output_data;
signals:
public slots:
};
#endif // CALCULATE_H
#ifndef WIDGET_H
#define WIDGET_H
#include "calculate.h"
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
struct mouse_data
{
int mouseClick_count;
QPointF mousePos1;
QPointF mousePos2;
QPointF mousePos;
};
explicit Widget(QWidget *parent = 0);
~Widget();
void paint(QPainter* painter);
protected:
void paintEvent(QPaintEvent *);
void mouseMoveEvent(QMouseEvent *mouseMoveEvent);
void mousePressEvent(QMouseEvent *);
private:
mouse_data m_mouse_data;
Calculate *P_calculate;
Calculate::Input_T m_Input_data;
Calculate::Output_T m_Output_data;
QPolygonF m_polygon;
private slots:
void Set_K(int);
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
#include <QDebug>
#include <QMouseEvent>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
this->setMouseTracking(true);
m_mouse_data.mouseClick_count=0;
m_Input_data.Angle_offset=60;
m_Input_data.pos_O=QPointF(width()/2,height()/2);
m_Input_data.pos_A=m_Input_data.pos_O-QPoint(100,100);
m_Input_data.H=0;
m_Input_data.W=0;
P_calculate=new Calculate(&m_Input_data);
m_Output_data=*P_calculate->Result(&m_Input_data);
connect(ui->horizontalSlider,SIGNAL(sliderMoved(int)),this,SLOT(Set_K(int)));
}
void Widget::paintEvent(QPaintEvent *paintEvent)
{
m_Output_data=*P_calculate->Result(&m_Input_data);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing,true);
QPen pen;
pen.setWidth(3);
painter.setPen(pen);
QPolygonF polygon;
polygon<<m_Output_data.point[0]<<m_Output_data.point[1]<<m_Output_data.point[2]<<m_Output_data.point[3];
if(m_mouse_data.mouseClick_count==0)
{
polygon.translate(m_mouse_data.mousePos-m_Input_data.pos_O);
}
painter.drawPolygon(polygon, Qt::WindingFill);
}
void Widget::mouseMoveEvent(QMouseEvent *mouseMoveEvent)
{
qDebug()<<"Move:"<<mouseMoveEvent->pos();
if(m_mouse_data.mouseClick_count==0)
{
m_mouse_data.mousePos=mouseMoveEvent->pos();
repaint();
}
else if(m_mouse_data.mouseClick_count==1)
{
m_mouse_data.mousePos2=mouseMoveEvent->pos();
m_Input_data.pos_A=m_mouse_data.mousePos2;
repaint();
}
}
void Widget::mousePressEvent(QMouseEvent *mousePressEvent)
{
qDebug()<<"press:"<<mousePressEvent->pos();
m_mouse_data.mouseClick_count++;
if(m_mouse_data.mouseClick_count==1)
{
m_mouse_data.mousePos1=mousePressEvent->pos();
m_mouse_data.mousePos=mousePressEvent->pos();
m_Input_data.pos_O=m_mouse_data.mousePos1;
}
else if(m_mouse_data.mouseClick_count==2)
{
m_mouse_data.mousePos2=mousePressEvent->pos();
m_Input_data.pos_A=m_mouse_data.mousePos2;
}
else if(m_mouse_data.mouseClick_count>2)
{
m_mouse_data.mouseClick_count=0;
m_mouse_data.mousePos=mousePressEvent->pos();
}
repaint();
}
void Widget::Set_K(int K)
{
qDebug()<<K;
m_Input_data.Angle_offset=K;
ui->label->setText(QString::fromLocal8Bit("角度K: %1°").arg(K));
repaint();
}
Widget::~Widget()
{
delete ui;
}