想将绘图加入事件循环共有两种方式:绘图事件和定时器事件

从Qt官方给的例程可以看出,如果想将绘图加入事件循环共有两种方式:绘图事件和定时器事件两种方式,通常使用前者。

(一) painterEvent

在绘图事件中,如果想使用update()刷新页面是行不通的,除非使用新的定时器定时刷新页面。painterEvent来自QWidget的virtual protected function,其他一些控件例如QLabel、QLineEdit、QMenuBar等的painterEvent也是继承QWidget的。所以这些有继承QWidget的类中基本都存在painterEvent。

————————————————

在画图之前需要前置知识点:

(1) Qt坐标系统

https://blog.csdn.net/hgcprg/article/details/53537106

https://www.cnblogs.com/lifexy/p/9203929.html

(二)TimerEvent

在timerEvent就比较容易控制绘图的刷新了,因为是定时器事件,可以控制时间。在官方例程中也提供了这种方法:

/**
*    PathDeform.h
*/
#ifndef PATHDEFORM_H
 #define PATHDEFORM_H
 
 #include "arthurwidgets.h"
 #include <QPainterPath>
 #include <QBasicTimer>
 #include <QDateTime>
 class PathDeformRenderer : public ArthurFrame
 {
     Q_OBJECT
     Q_PROPERTY(bool animated READ animated WRITE setAnimated)
     Q_PROPERTY(int radius READ radius WRITE setRadius)
     Q_PROPERTY(int fontSize READ fontSize WRITE setFontSize)
     Q_PROPERTY(int intensity READ intensity WRITE setIntensity)
     Q_PROPERTY(QString text READ text WRITE setText)
 public:
     PathDeformRenderer(QWidget *widget, bool smallScreen = false);
     void paint(QPainter *painter);
     void mousePressEvent(QMouseEvent *e);
     void mouseReleaseEvent(QMouseEvent *e);
     void mouseMoveEvent(QMouseEvent *e);
     void timerEvent(QTimerEvent *e);
     QSize sizeHint() const { return QSize(600, 500); }
     bool animated() const { return m_animated; }
     int radius() const { return int(m_radius); }
     int fontSize() const { return m_fontSize; }
     int intensity() const { return int(m_intensity); }
     QString text() const { return m_text; }
 
 public slots:
     void setRadius(int radius);
     void setFontSize(int fontSize) { m_fontSize = fontSize; setText(m_text); }
     void setText(const QString &text);
     void setIntensity(int intensity);
     void setAnimated(bool animated);
 signals:
     void clicked();
 private:
     void generateLensPixmap();
     QPainterPath lensDeform(const QPainterPath &source, const QPointF &offset);
 
     QBasicTimer m_repaintTimer;
     QTime m_repaintTracker;
     QVector<QPainterPath> m_paths;
 .......
 };///
 
/**
*    PathDeform.cpp
*/
 void PathDeformRenderer::timerEvent(QTimerEvent *e)
 {
     if (e->timerId() == m_repaintTimer.timerId()) { //判断定时器id是否绘图定时器的ID
         if (QLineF(QPointF(0,0), m_direction).length() > 1)
             m_direction *= 0.995;
         qreal time = m_repaintTracker.restart();
         QRect rectBefore = circle_bounds(m_pos, m_radius, m_fontSize);
         qreal dx = m_direction.x();
         qreal dy = m_direction.y();
         if (time > 0) {
             dx = dx * time * .1;
             dy = dy * time * .1;
         }
         m_pos += QPointF(dx, dy);
         if (m_pos.x() - m_radius < 0) {
             m_direction.setX(-m_direction.x());
             m_pos.setX(m_radius);
         } else if (m_pos.x() + m_radius > width()) {
             m_direction.setX(-m_direction.x());
             m_pos.setX(width() - m_radius);
         }
         if (m_pos.y() - m_radius < 0) {
             m_direction.setY(-m_direction.y());
             m_pos.setY(m_radius);
         } else if (m_pos.y() + m_radius > height()) {
             m_direction.setY(-m_direction.y());
             m_pos.setY(height() - m_radius);
         }
 #ifdef QT_OPENGL_SUPPORT
         if (usesOpenGL()) {
             update();
         } else
 #endif
         {
             QRect rectAfter = circle_bounds(m_pos, m_radius, m_fontSize);
             update(rectAfter | rectBefore);
             QApplication::syncX();
         }
     }
 }
 void PathDeformRenderer::mouseReleaseEvent(QMouseEvent *e)
 {
     if (e->buttons() == Qt::NoButton && m_animated) {
         m_repaintTimer.start(10, this);
         m_repaintTracker.start();
     }
     if (!m_mouseDrag && m_smallScreen)
         emit clicked();
 }

然后其他地方启动绘图的定时器即可。

https://blog.csdn.net/rabbittinbee/article/details/97808810

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值