1.调试过程中可知,鼠标每次到ui时候 会触发paintEvent事件
我把这次触发叫做 空跑 因为它没有执行你想操作的事件 比如鼠标,按键等
paintEvent的触发
(1)鼠标选中 或者在ui上晃悠的时候触发
(2)update() 执行后 这个事件已经触发 但是要执行万当前函数的代码 才会到paintEvent中执行你的代码,这个来源于实际的调试经验。
2.由于本人单片机经验,对QT的事件触发做一下理解
一开始将事件触发当作是中断
只要有事件发生 它就要跑到对应的函数中进行操作
但实际中 需要将本个函数块中的执行完毕 在跑到对应的事件触发函数中
对此 个人理解为 本个函数块中 有触发其他函数块的事件 QT先把这个时间记录下来 然后 执行完本函数块之后 再执行对应的触发事件。
3.双缓冲区绘图
双缓冲区 绘图时,将所有内容绘制到一个绘图设备(QPixmap),再将整个图像绘制到部件上显示出来
使用双缓冲区绘图 可以避免绘图时的闪烁现象,
具体应用:鼠标拖动绘制矩形的过程中
4 实现内容 按键按下 自动绘制矩形 按下对应按键 清除画板上的内容 鼠标拖动绘制矩形
头文件
#ifndef WIDGET_H
#define WIDGET_H
#include
#include
#include
#include
#include
#include
#include
#include
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
QPixmap Pix;
QPixmap tempPix;//临时缓冲区
QPoint startPoint;
QPoint endPoint;
bool isDrawing;//是否正在绘图的标志`
bool clear_Flag;//清空标志
public:
void paintEvent(QPaintEvent *event);
void draw_point(int const x,int const y,QColor const c,int const w);
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
private slots:
void on_beginpushButton_clicked();
void on_clearpushButton_2_clicked();
};
#endif // WIDGET_H
cpp 源代码
#include "widget.h"
#include "ui_widget.h"
//可以去看Qcustomer
#define WIN_WIGHT 200
#define WIN_HEIGHT 200
#define WIN_TITLE "画图测试"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//初始化QPixmap
Pix = QPixmap(WIN_WIGHT,WIN_HEIGHT);
Pix.fill(Qt::white);
tempPix=Pix;
isDrawing=false;
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent *event)
{
//QPainter painter(this); //表示在当前的窗口绘制图形 会自动的开始和结束
//painter.drawLine(QPoint(0,0),QPoint(100,100));
// QPainter painter;//没有指定窗口 需要自己写 begin end 和上面那段代码d等效
//painter.begin(this);//this 当前窗口的指针 //QPainter::QPainter ( QPaintDevice * device)
//painter.drawLine(QPoint(0,0),QPoint(100,100));
//painter.end();
int x=startPoint.x();
int y=startPoint.y();
int width=endPoint.x()-x;
int height=endPoint.y()-y;
//如果有清空标志
if(clear_Flag==1)
{
x=0;
y=0;
width=0;
height=0;
}
QPainter painter;
painter.begin(&tempPix);
painter.drawRect(x,y,width,height);
painter.end();
painter.begin(this);
painter.drawPixmap(0,0,tempPix);
//如果已经完成了绘制 更新缓冲区
if(!isDrawing){
Pix=tempPix;
}
}
void Widget::mousePressEvent(QMouseEvent *event){
if(event->button()==Qt::LeftButton){
clear_Flag=0;
//鼠标按下左键 获取当前位置作为矩形的开始点
startPoint =event->pos();
isDrawing=true;
}
}
void Widget::mouseReleaseEvent(QMouseEvent *event){
if(event->button()==Qt::LeftButton){
clear_Flag=0;
//当鼠标左键松开时候 获取当前位置为结束点
endPoint=event->pos();
//标记已经绘制结束
isDrawing=false;
update();
}
}
void Widget::mouseMoveEvent(QMouseEvent *event){
if(event->buttons()&Qt::LeftButton){
clear_Flag=0;
//按下鼠标左键进行移动 获取当前位置为结束点 绘制矩形
endPoint=event->pos();
//将缓冲区内容复制到临时缓冲区,进行动态绘图
//每次都在缓冲区的图像的基础上进行绘图 这样不会出现重影
tempPix=Pix;
//更新显示
update();
}
}
void Widget::on_beginpushButton_clicked()
{
clear_Flag=0;
int x=qrand()%100;
int y=qrand()%100;
//draw_point(x,y,QColor(10,20,20),10);
startPoint.setX(0);
startPoint.setY(0);
isDrawing=true;
endPoint.setX(x);
endPoint.setY(y);
tempPix=Pix;
isDrawing=false;
update();
clear_Flag=0;
}
void Widget::on_clearpushButton_2_clicked()
{
clear_Flag=1;
Pix.fill(Qt::white);
tempPix=Pix;
update();
}
最后致谢:霍亚飞
附:本人新手小白 搞上面这个大概花了5-10 个小时 功能基本实现
上面描述中个人理解如有错误 请大神斧正!