QWidget 实现原理调查

前言

QWidget实际上就是个壳,用来标记脏区域,处理一些事件。

1、首先update, repaint 最终都调用

QWidgetPrivate::syncBackingStore,

2、QWidgetPrivate::syncBackingStore 相关流程,最终调用endPaint进入平台层 , 调入void QFbBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)

1 QBackingStore::flush qbackingstore.cpp 117 0x1189bd4f
2 QWidgetBackingStore::qt_flush qwidgetbackingstore.cpp 154 0x7b541dc
3 QWidgetBackingStore::flush qwidgetbackingstore.cpp 1400 0x7b5618a
4 QWidgetBackingStore::endPaint qwidgetbackingstore.cpp 359 0x7b563c5
5 QWidgetBackingStore::doSync qwidgetbackingstore.cpp 1384 0x7b579da
6 QWidgetBackingStore::sync qwidgetbackingstore.cpp 1162 0x7b57df3
7 QWidgetPrivate::syncBackingStore qwidget.cpp 1973 0x7b716e8

3、paintEvent相关调用流程

1 QWidget::event qwidget.cpp 9055 0x1443b556
2 Widget::event widget.cpp 29 0x401d0f
3 QApplicationPrivate::notify_helper qapplication.cpp 3722 0x143f85be
4 QApplication::notify qapplication.cpp 3685 0x14401f5b
5 QCoreApplication::notifyInternal2 qcoreapplication.cpp 1024 0x1183057
6 QCoreApplication::sendSpontaneousEvent qcoreapplication.h 236 0x144336ee
//这里发送 QEvent::Paint
7 QWidgetPrivate::sendPaintEvent qwidget.cpp 5715 0x144336ee

8 QWidgetPrivate::drawWidget qwidget.cpp 5655 0x1443423d
9 QWidgetBackingStore::doSync qwidgetbackingstore.cpp 1381 0x144079b4
10 QWidgetBackingStore::sync qwidgetbackingstore.cpp 1136 0x14407c59
11 QWidgetPrivate::syncBackingStore qwidget.cpp 1982 0x14421667

paintEvent 在 endPaint之前,如果在paintEvent里就开始传出画面,这时候最新的画面还没有刷出来
// Paint the rest with composition.
if (repaintAllWidgets || !dirtyCopy.isEmpty()) {
const int flags = QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawRecursive;
//这里会最终会调用painterEvent
tlw->d_func()->drawWidget(store->paintDevice(), dirtyCopy, tlwOffset, flags, 0, this);
}

4、endPaint里才是真是的绘制

endPaint(toClean, store, &beginPaintInfo);

case QEvent::Paint:
    // At this point the event has to be delivered, regardless
    // whether the widget isVisible() or not because it
    // already went through the filters
    paintEvent((QPaintEvent*)event);
    break;
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Qt中实现一个LED灯效果,可以使用QWidget类自定义一个LED小部件。以下是一个简单的示例代码: ```cpp #include <QtWidgets> class LEDWidget : public QWidget { public: LEDWidget(QWidget *parent = nullptr) : QWidget(parent), m_on(false) { setFixedSize(20, 20); // 设置小部件的固定大小 } void setOn(bool on) { m_on = on; update(); // 更新小部件的绘制 } protected: void paintEvent(QPaintEvent *event) override { Q_UNUSED(event); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); // 抗锯齿 painter.setBrush(m_on ? Qt::red : Qt::darkRed); // 根据状态设置画刷颜色 QRectF rect(0, 0, width(), height()); painter.drawEllipse(rect); // 在小部件内绘制圆形 if (m_on) { painter.setPen(Qt::white); painter.drawEllipse(rect.adjusted(2, 2, -2, -2)); // 绘制内部的白色圆形 } } private: bool m_on; }; int main(int argc, char *argv[]) { QApplication app(argc, argv); LEDWidget ledWidget; ledWidget.show(); QTimer timer; QObject::connect(&timer, &QTimer::timeout, [&ledWidget]() { static bool on = false; ledWidget.setOn(on); on = !on; }); timer.start(500); // 每隔500毫秒切换LED灯的状态 return app.exec(); } ``` 在上面的示例中,我们创建了一个名为LEDWidget的自定义QWidget类,它重写了paintEvent()函数来绘制LED灯的效果。通过设置painter的画刷颜色和绘制圆形,我们可以实现LED灯的开关效果。在main()函数中,我们创建了一个LEDWidget实例,并使用QTimer定时器来切换LED灯的状态。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值