【发布时间】:2018-04-19 21:19:06
【问题描述】:
我的应用程序将 3D 渲染绘制到离线 QImage(由于历史原因没有使用 OpenGL),然后在这样的小部件中绘制 QImage:
void Render3dModel::paintEvent(QPaintEvent *event) {
// Update model and render new image
m_model.calculate();
QImage image = m_model.getImage();
// Draw image in widget
QPainter painter(this);
painter.drawImage(QPointF(0, 0), image);
}
使用 QWidget::update() 根据鼠标移动重新绘制图像:
void Render3dModel::mouseMoveEvent(QMouseEvent *event) {
m_model.rotate(event);
update();
}
这种方法在 Qt 5.6 和 Qt 5.9 中运行迅速且完美无缺。然而,在 Qt 5.10 中重建完全相同的代码会导致奇怪的故障。两个帧的一部分同时可见。这不是临时效果(例如延迟绘图),因为如果我停止移动鼠标,它实际上会一直显示两帧部分。下面是一个例子(为了清晰起见,使用交替的灰色和白色背景来表示偶数/奇数帧):
我尝试在QImage 环形缓冲区中使用image.copy() 创建深层副本,以查看这是否是QImage 的销毁/重用和一些延迟/延迟绘制之间的某种竞争条件,但这无济于事。
显然QPainter 的机制在 Qt 5.9 和 Qt 5.10 之间发生了变化,但我在文档中找不到任何线索。
请指教
更新
在玩了几个窗口大小之后,我得出的结论是,故障以某种方式对应于左上角与“截面尺寸”标签的“S”对齐的相同大小的矩形。但是,正如您在屏幕截图中看到的那样,具有白色背景的框架将圆锥的那部分绘制在正确的位置。所以图像不是移位,而是以某种方式剪辑?!
我已经尝试添加
painter.setClipping(false);
painter.setClipRect(QRect(0, 0, size().width(), size().height()));
但这没有任何效果。我的Render3dModel 偶尔会从它的父母那里得到paintEvent 吗?
更新 2
在下面 Kuba Ober 的最小示例中添加 mouseMoveEvent 处理程序,可以在 MacBook(OS X 10.12.6,Intel HD Graphics 515)上重现该问题:
这可能是 Qt 5.10 中的回归,因为我无法在 Qt 5.9 中重现它吗?我应该提交错误报告吗?
更新 3
这似乎确实是 OS X 上 Qt 5.10 中的回归。已提交错误报告 https://bugreports.qt.io/browse/QTBUG-67998
【问题讨论】:
-
不,
Render3dModel没有从它的父母那里获得绘画事件。如果是这样,那么您已经破坏了进程的执行状态。 Qt 不做这些事情。 -
我想我知道您的问题可能是什么:您在某处使用了错误的尺寸。检查图像和
Render3dModel的大小是否正确! -
它只需重复发出
update()即可重现,无需鼠标事件。这确实是一个 Qt 5.10 回归。