赞
踩
事件机制主要可以分为两类
1.在与用户交互时发生,比如按下鼠标(mousepressEvent),敲键盘(可以pressEvent)等。
2.系统自动发生,比如计时器事件(timerEvent)。
当发生事件,比如点击鼠标或键盘,就会产生一个QEvent对象,这里注意QT中所有的事件类都继承于QEvent,这个QEvent对象会传给当前组件的event函数,如果没有事件过滤器,则该函数会按照事件对象的类型发送到特定的xxxEvent事件处理函数中进行处理。
1.鼠标移动:mouseMoveEvent()
2.鼠标单击:mousePressEvent()
3.鼠标双击:mouseDoubleClickEvent()
4.鼠标弹起:mouseReleaseEvent()
5.鼠标滚轮:wheelEvent()
6.键盘按下:keyPressEvent()
7.键盘弹起:keyReleaseEvent()
这些函数都是虚函数,这意味着我们可以在子类中进行重写,来达到我们想要的功能!!!
那么我们看一段代码来理解一下吧,在下面这段代码中我们重写了上述几种常见的事件来达到演示的效果:
1.鼠标移动事件
- //鼠标移动事件
- void Widget::mouseMoveEvent(QMouseEvent *event)
- {
- qDebug() << "鼠标移动事件" << event->pos();
- pos = event->pos(); //鼠标点击坐标
- update(); //强制激发一次绘图事件
- }
当我们移动鼠标可以看到我们打印的鼠标所在位置发生改变:
2.鼠标单击以及鼠标按键释放
- void Widget::mousePressEvent(QMouseEvent *event)
- {
- qDebug() << "鼠标单击" << event->button();
- mouseReleased = false;
- pos = event->pos(); //鼠标点击坐标
- update(); //强制激发一次绘图事件
- }
-
- //重写鼠标弹起事件的处理动作
- void Widget::mouseReleaseEvent(QMouseEvent *event)
- {
- mouseReleased = true;
- update();
- qDebug() << "鼠标弹按键释放" << event->button();
- }
当我们点击鼠标释放后可以看到下面情况:
可以看出1和2分别就代表了我们的鼠标左键和右键 !!
3.鼠标双击和滚轮事件
-
- //重写鼠标双击事件的处理动作
- void Widget::mouseDoubleClickEvent(QMouseEvent *event)
- {
- qDebug() << "鼠标双击" << event->button();
- }
-
- //滚轮事件
- void Widget::wheelEvent(QWheelEvent *event)
- {
- qDebug() << "滚轮事件" << event->delta();
- }
当我们双击鼠标滑动滚轮可以看到下面的结果;
4.键盘按下和弹起
- //键盘按下事件
- void Widget::keyPressEvent(QKeyEvent *event)
- {
- qDebug() << "键盘按下事件" << event->key();
- }
-
- //键盘弹起事件
- void Widget::keyReleaseEvent(QKeyEvent *event)
- {
- qDebug() << "键盘释放事件" << event->key();
- }
我分别按下了qwe键,看看结果:
分别显示了他们对应的ASCII值,到此我们了解了我们是可以对事件进行重写的,基于这个那我们就可以完成一些更高级的操作了!!
5.绘图事件PaintEvent
- Widget::Widget(QWidget *parent)
- : QWidget(parent)
- {
- //startTimer(50); //启动内置定时器,以产生周期性的定时器事件(激活timerEvent())
- //setMouseTracking(true); //不用按住鼠标左键,也可以捕获鼠标移动事件
-
- pix = new QPixmap(640, 480); //图片缓冲
- pix->fill();
- mouseReleased = true;
- }
- QPainter p(this);
- p.drawPoint() 点
- p.drawLine() 直线
- p.drawRect() 矩形
- p.drawEllipase() 椭圆
- p.drawText()画文字
- p.drawPixmap()画图
看第一段演示代码:
1.画点线矩形圆图片文字
- void Widget::paintEvent(QPaintEvent *event)
- {
- qDebug() << "paint event !!!!!";
-
- //画用户自己的想法
- QPainter p(this);
- QPen pen; //画笔,画线用
- pen.setWidth(10);
- p.setPen(pen);//设置画笔的粗细
-
- QBrush brush;//画刷,画填充
- brush.setColor(Qt::red);//设置颜色
- brush.setStyle(Qt::DiagCrossPattern);//设置网格笔刷
- p.setBrush(brush);
-
- p.drawPoint(pos); //画点
- p.drawLine(QPoint(0, 0), pos); //画线,起始坐标到鼠标点的坐标
- p.drawRect(0, 0, pos.x(), pos.y()); //画矩形
- p.drawEllipse(pos, 200, 100); //画椭圆
- p.drawText(pos.x(), pos.y(), "你好"); //画文字
-
- //画图片
- p.drawPixmap(pos.x(), pos.y(), 100, 100, QPixmap("图片路径"));
- }
看看运行结果:
2.画家和界面有各自的坐标系,我们可以移动画家的位置可以缩放
p.translate();移动
p.scale() 缩放
p.rotate()旋转:
- void Widget::paintEvent(QPaintEvent *event)
- {
- qDebug() << "paint event !!!!!";
- QPainter p(this);
- p.translate(width()/2, height()/2); //移动画家
- p.rotate(30); //转动画家坐标系
- p.drawLine(QPoint(0, 0), QPoint(100, 0));
- p.scale(0.5, 0.5); //画家缩放
- p.drawEllipse(QPoint(0, 0), 100, 100);
- p.drawEllipse(QPoint(width()/2, height()/2), 100, 100);
- }
看看结果:很明显我们移动了画家的位置以及旋转了坐标系
3.但每次我们要画下一个图,前面我们画的图形就会消失,于是有了双缓冲画法,可以将历史记录进行保存,在下次画的时候也能保留原来的图形:
-
- /*双缓冲绘制*/
- void Widget::paintEvent(QPaintEvent *event)
- {
- qDebug() << "paint event !!!!!";
-
- QPainter p(this);
- //1. 画上一次的历史记录
- p.drawPixmap(0, 0, *pix);
-
- //2. 画用户自己的新内容
- p.drawLine(QPoint(0, 0), pos); //画线
-
- if(mouseReleased) //鼠标弹起了
- {
- //3. 画到历史记录里
- QPainter p1(pix);
- p1.drawLine(QPoint(0, 0), pos);
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。