关于用QPainter画过大的图片出现问题的原因

起源

CSDN上有网友问到:

在qpixmap(40000,100)上画图到x=32768之后就画不出来了怎么办验证

写段代码测试一下:

import sys
from PySide import QtCore, QtGui

app = QtGui.QApplication(sys.argv)
pix = QtGui.QPixmap(40000, 100)
p = QtGui.QPainter(pix)
p.setPen(QtCore.Qt.red)
p.drawLine(0, 50, 40000, 50)
pix.save("abcd.png")
sys.exit(app.exec_())

结果确实如网友所说:一条直线,无故终止了。

原因

原因何在呢?打开google,搜索,再搜索,依然无果。于是,还是看源码吧:

Qt 的 Paint System 由三部分构成

  • QPainter
  • QPaintEngine
    • QRasterPaintEngine
  • QPaintDevice
    • QPixmap

对我们这个情况来说,QPainter 不用多说,QPixmap 是 QPaintDevice 的派生类,也容易理解。唯独 QPaintEngine 比较隐蔽, 我们这儿关注的是它的派生类 QRasterPaintEngine

$QTDIR/src/gui/painting/qpaintengine_raster.cpp

函数调用 关系:

  • QPainter::QPainter(QPaintDevice *pd)

    • bool QPainter::begin(QPaintDevice *pd)

      • bool QRasterPaintEngine::begin(QPaintDevice *device)

        • void QRasterPaintEnginePrivate::systemStateChanged()

看看 systemStateChanged() 的代码:

void QRasterPaintEnginePrivate::systemStateChanged()
{
QRect clipRect(0, 0,
qMin(QT_RASTER_COORD_LIMIT, device->width()),
qMin(QT_RASTER_COORD_LIMIT, device->height()));

if (!systemClip.isEmpty()) {
QRegion clippedDeviceRgn = systemClip & clipRect;
deviceRect = clippedDeviceRgn.boundingRect();
baseClip->setClipRegion(clippedDeviceRgn);
} else {
deviceRect = clipRect;
baseClip->setClipRect(deviceRect);
}
...
}

发现什么没?有一个宏出现了 QT_RASTER_COORD_LIMIT,其数值为 32767

这样一来,PainterEngine 中的设备大小始终不会超出这个值,而 QPainter 要通过 PainterEngine 实现在 QPainteDevice 中的图线绘制。于是,结果就是我们一开始所看到的了。


看来出了问题一味的求助于google是不够的,有时反而会浪费很多时间,查看源码往往是最直接,最快的方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值