1、绘图事件 QPaintEvent
重构虚函数 virtual void paintEvent(QPaintEvent* ev)
一个简单的例子:
画个斜线,两个正方形
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPaintEvent>
#include <Qpainter>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
protected:
//重写虚函数
virtual void paintEvent(QPaintEvent* ev);
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent *ev)
{
QPainter paint;
paint.begin(this);//必须有一个开始
//画一条(0,0)到(100,100)的线段
paint.drawLine(0,0,100,100);
//画两个矩形
paint.drawRect(100,100,100,100);
paint.drawRect(75,75,150,150);
update(); //然后update才能显示
paint.end();
}
2、一个小demo(绘图和鼠标、按键结合)
说明: 鼠标点下之后可以画线段,松开之后结束,按键按下ctrl+z之后消除上一条线段
需要重写的虚函数
virtual void paintEvent(QPaintEvent *ev);
virtual void keyPressEvent(QKeyEvent* ev);
virtual void mousePressEvent(QMouseEvent *ev);
virtual void mouseMoveEvent(QMouseEvent *ev);
virtual void mouseReleaseEvent(QMouseEvent *ev);
画线段就是,鼠标点击记录开始点,然后在触发鼠标移动的过程中,记录第一个结束点,该点和开始点组成线段,开始点等于移动结束的点,下次触发继续组成线段,将这些线段存到容器中然后统一用paint画出来就好了。
具体代码如下
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QKeyEvent>
#include <QPaintEvent>
#include <QPoint>
#include <QPainter>
#include <QLine>
#include <QMouseEvent>
#include <QDebug>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
QPainter painter;
QVector<int> count;
QVector<QLine> v;
QPoint start;
QPoint end;
int num;
protected:
virtual void paintEvent(QPaintEvent *ev);
virtual void keyPressEvent(QKeyEvent* ev);
virtual void mousePressEvent(QMouseEvent *ev);
virtual void mouseMoveEvent(QMouseEvent *ev);
virtual void mouseReleaseEvent(QMouseEvent *ev);
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent *ev)
{
Q_UNUSED(ev);
painter.begin(this);
painter.drawLines(v);
update();
painter.end();
}
void Widget::keyPressEvent(QKeyEvent *ev)
{
if(ev->modifiers() == Qt::ControlModifier && ev->key() == Qt::Key_Z){
qDebug()<<"ctrl+Z";
if(!v.isEmpty()){
//清空上一段线段在vector中的记录
v.remove(v.size()-count.last(),count.last());
}
if(!count.isEmpty()){
//删除最后一个个数
count.pop_back();
}
//更新一下
update();
}
}
void Widget::mousePressEvent(QMouseEvent *ev)
{
start = ev->pos();
num = v.size();
}
void Widget::mouseMoveEvent(QMouseEvent *ev)
{
// 移动的过程其实是很多个小线段,所以只需要给将开始和结束的点链接起来即可
end = ev->pos();
QLine line(start,end);
//把线段存进vector中
v.push_back(line);
start = end;
}
void Widget::mouseReleaseEvent(QMouseEvent *ev)
{
Q_UNUSED(ev);
//存放本次线段的个数
count.push_back(v.size()-num);
}
具体效果