1. RasterWindow 运行结果
2. AnalogClockWindow 运行结果
3. 最重要是这个工程管理 , 将已有得工程代码的类引入新工程
4. 重写render和timerEvent
5. 窗口第一次显示、被遮挡后重新露出来时触发
6. 窗口大小改变,调整缓冲区大小。
7. 统一接收事件,内部分发处理。
8. renderNow 马上重绘, renderLater 走事件![]()
9. 触发时机
- 用户拉大窗口 → Qt 触发
resizeEvent(),m_backingStore->resize()重新分配画布内存。 - 窗口暴露,触发
exposeEvent(),直接调用renderNow(),立刻画出第一帧时钟。 - 定时器每 1 秒触发:调用
renderLater();- 只是调用
requestUpdate()投递事件,函数马上返回; - 事件循环空闲,收到
UpdateRequest,调用renderNow()刷新时钟画面。
- 只是调用
10 . 两种方式处理
10.1 延时绘图
业务代码调用 renderLater()
↓
requestUpdate() → 往事件队列扔 QEvent::UpdateRequest
↓(函数立刻返回,不画图,等待事件循环)
Qt事件循环分发事件 → RasterWindow::event()捕获UpdateRequest
↓
调用 renderNow() 【进入真正绘制】
↓
renderNow内部调用 render(painter) 【执行你的绘图代码:画时钟、指针、刻度】
↓
绘制完成 flush(),画面出现在屏幕
10.2 立即绘图
窗口暴露/重新显示 → exposeEvent
↓
直接调用 renderNow() (不走事件队列,同步立刻画)
↓
renderNow()内部调用 render(painter)
↓
flush上屏
总结
总结
1. 工程管理,子工程
- Qt中可以使用
subdirs模板管理多个子工程,一个pro主项目管理多个子pri/pro模块。 - 子工程可以把功能拆分,实现代码模块化,方便复用,例如示例中
rasterwindow作为基础模块给时钟示例调用。
2. 绘图和事件(QWindow底层光栅绘图 RasterWindow)
核心类
QWindow:底层原生窗口,非QWidget,本身不能直接QPainter绘图。QBackingStore:离屏光栅缓冲区,所有绘制先画在内存,最后flush刷新到屏幕,防止闪烁。
三个绘图函数关系
- renderLater():异步重绘,调用
requestUpdate()投递UpdateRequest事件;只发请求,不执行绘图,等价QWidget的update()。 - renderNow():同步立即绘制;管理
QBackingStore缓冲区、创建QPainter,内部调用虚函数render(),最后flush上屏;等价QWidget的repaint()。 - render(QPainter *):虚回调钩子函数,子类重写,只写业务绘图代码(translate、rotate、绘制图形),不管理缓冲区。
调用链路:
renderLater()→ 投递更新事件 → event捕获事件 →renderNow()→render(painter)→ flush屏幕
窗口事件
resizeEvent:窗口大小变化,调整QBackingStore缓冲区内存大小,不负责绘图。exposeEvent:窗口显示、解除遮挡,调用renderNow()立刻绘制第一帧画面。event():捕获QEvent::UpdateRequest事件,触发renderNow()执行绘制。
坐标系关键点
- QWindow绘图Y轴向下;
painter.rotate(正数):坐标系逆时针旋转,视觉上图形顺时针偏转。