小白QT之QGraphicsScene场景视图

用最接地气的比喻来说,整个过程就像你在玩一个"客厅摄像头直播"游戏。

  • QGraphicsScene = 你家客厅(一个超级大的、无边界的空间)
  • QGraphicsItem = 客厅里摆放的各种家具、玩具、挂画、灯......(这些东西才是真正要被看到的"内容")
  • QGraphicsView = 你架在客厅里的一个摄像头 + 显示器(它决定观众最终在屏幕上看到什么)

关键一句话:客厅本身是不会出现在电视上的,只有摄像头拍到的画面才会显示。

整个绘制是怎么一步步发生的?

  1. 某件事触发了"需要重新画画面"
    比如:
  • 窗口第一次显示出来
  • 你拖动了视图(像转动摄像头)
  • 你滚轮缩放了(像变焦镜头)
  • 你移动了某个家具(某个 Item 位置变了)
  • 你手动调用了 update() 或 scene->invalidate()

2.摄像头(QGraphicsView)收到"要重画"的信号

它会先问自己:"我现在对着客厅的哪个区域?要拍多大的范围?"

它根据当前的

  • 缩放比例
  • 平移位置
  • 旋转角度
    计算出"我现在能看到客厅的哪一块矩形区域"(这个区域用场景坐标表示)

3.摄像头对客厅喊:"给我把这个区域的东西都画出来!"

4.客厅(QGraphicsScene)收到请求,开始按顺序整理和绘画

客厅会分几个大阶段画(从最底层画到最上层):

  • 先画背景(你设置的纯色、网格、图片背景......)
  • 然后画所有家具(也就是所有的 QGraphicsItem)
  • 最后画前景(比如你自己加的水印、调试用的坐标尺......)

最关键、最花时间的其实是第二步------画家具

5.客厅怎么知道该画哪些家具、不该画哪些?

它会先看"摄像头要拍的这个矩形区域",然后快速找一找: "哪些家具哪怕只露一点点在这个区域里?"

(Qt 内部用一种叫 BSP 树的空间索引来快速找,通常比暴力遍历快非常多)

找到这些"可能要画到的家具"之后,客厅会把它们按 z 值从低到高 排好队(z 值大的会盖在 z 值小的上面,就像前景盖背景一样)

6.轮到每个家具自己上场表演了

客厅会一个接一个地把"画笔"交给每个家具,说:

"现在轮到你了,你画你自己吧!"

每个家具(QGraphicsItem)就会执行自己的 paint() 函数:

void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)

{

painter->setBrush(Qt::blue);

painter->drawEllipse(-20, -20, 40, 40); // 画一个圆

painter->drawText(0, 0, "我是小球");

}

注意:这时 painter 已经自动处于这个家具自己的坐标系里了,(0,0) 就是这个家具的中心点或你定义的原点,你不用管它在客厅的绝对位置。

7.所有家具都画完后

客厅把这一整张画好的"大图"交给摄像头

8.摄像头(View)把这张图显示到电视屏幕(也就是窗口)上

完成了!观众(用户)就看到画面了。

小结:

"场景管东西,视图管镜头"

  • 东西(家具)放在场景(客厅)里
  • 镜头(视图)决定拍哪里、怎么拍(放大缩小旋转平移)
  • 要重画时 → 镜头告诉场景:给我看这个区域
  • 场景按顺序(背景 → 家具按 z 排序 → 前景)画
  • 每个家具自己负责把自己画出来
  • 镜头把画好的画面显示到屏幕

常见坑:

  • 忘记写 boundingRect() → 家具等于隐身,什么都看不到
  • boundingRect() 写得太小 → 鼠标点不到、碰撞检测失效
  • 在 paint() 里面做超级复杂的计算 → 界面直接卡死
  • 改了数据却不调用 update() → 改了也看不见

往场景里一股脑塞几万几十万个小 Item → 不优化基本必崩

相关推荐
hqwest3 小时前
码上通QT实战27--系统设置02-加载用户列表
开发语言·qt·sqlite·qtablewidget
电子_咸鱼3 小时前
Linux IPC 实战:管道与共享内存的使用场景 + 底层原理全剖析
linux·运维·服务器·开发语言·网络·vscode·qt
yaso_zhang4 小时前
openssl版本匹配问题
qt
hqwest4 小时前
码上通QT实战28--系统设置03-用户管理布局
开发语言·qt·qdialog·模态窗体·非模态窗体·qwidget!
qq_401700415 小时前
Qt 线程管理:从 QThread 到 QThreadPool
qt
EniacCheng5 小时前
将QtNodes添加到Qt项目中
qt·qtnodes
JANG10246 小时前
【Qt】项目打包
开发语言·qt
SunkingYang6 小时前
QT中如何遍历QStringList中的一部分存储到另外一个QStringList
qt·遍历·子集·qstringlist·另一个
CSDN_RTKLIB6 小时前
【字符编码】文本文件与二进制文件
c++·qt