在加载图片的QPixmap上使用QPainter绘制线条无显示,求助原因
问题:在QPixmap加载的图片上绘制线条无法显示
我可以通过以下代码在QLabel上绘制一条蓝色线条,背景为红色:
QPixmap *myPixmap; myPixmap = new QPixmap(); myPixmap->fill(Qt::red); QPainter painter(myPixmap); painter.setPen(Qt::blue); painter.drawLine(1, 1, 50, 50); ui.label->setPixmap(*myPixmap);
这段代码能正常工作,得到带蓝色线条的红色标签。
但当我尝试在加载的图片(c:\temp\1.jpg)上绘制线条时,只能看到图片,看不到蓝色线条:
QPixmap *myPixmap; myPixmap = new QPixmap(ui.label->size()); myPixmap->load("c:\\temp\\1.jpg"); QPainter painter(myPixmap); painter.setPen(Qt::blue); painter.drawLine(1, 1, 50, 50); ui.label->setPixmap(*myPixmap);
系统环境:Win10 + Qt5.6.1
补充说明(编辑后)
经提醒发现线条其实存在,只是因为超出主窗口可视范围没被看到。原图片是纯色背景所以没注意到,给图片添加边框后可以对比:
- 带线条截图:图片左上角区域有蓝色线条,但该区域超出了主窗口的显示范围
- 不带线条截图:图片左上角无蓝色线条,仅显示图片主体部分
原因与解决方案
核心原因
你创建QPixmap时指定了ui.label->size(),但调用load()加载图片后,QPixmap的尺寸会被重置为图片本身的尺寸。如果图片尺寸和标签尺寸不一致,你按标签尺寸绘制的线条坐标就会和图片实际尺寸不匹配,导致线条落在图片的可视区域之外,所以看不到。
比如:标签尺寸比图片大,加载图片后QPixmap缩小到图片尺寸,你画的(1,1)到(50,50)线条可能超出了图片范围;如果图片比标签大,QLabel默认只显示图片的部分区域,线条刚好在未显示的区域里。
修复方案
方案1:基于图片实际尺寸绘制
先加载图片,再根据图片的实际尺寸确定线条坐标,确保线条落在图片范围内:
QPixmap *myPixmap = new QPixmap(); // 先加载图片,确认加载成功 if (myPixmap->load("c:\\temp\\1.jpg")) { QPainter painter(myPixmap); painter.setPen(Qt::blue); // 示例:从左上角画到图片宽高1/4的位置,确保在可视范围内 painter.drawLine(1, 1, myPixmap->width()/4, myPixmap->height()/4); ui.label->setPixmap(*myPixmap); }
方案2:保持标签尺寸,先画图片再叠加线条
如果需要让图片适配标签的尺寸,先创建对应大小的QPixmap,将图片缩放绘制到上面后,再叠加线条:
QPixmap *myPixmap = new QPixmap(ui.label->size()); myPixmap->fill(Qt::transparent); // 填充透明背景 QPainter painter(myPixmap); // 将图片缩放绘制到QPixmap,适配标签尺寸 painter.drawPixmap(0, 0, ui.label->width(), ui.label->height(), QPixmap("c:\\temp\\1.jpg")); // 此时线条坐标基于标签尺寸,会显示在可视区域内 painter.setPen(Qt::blue); painter.drawLine(1, 1, 50, 50); ui.label->setPixmap(*myPixmap);
额外提示
QPixmap::load()成功后会自动重置QPixmap的尺寸,因此不要先指定尺寸再加载图片,除非你需要后续手动调整图片大小。- 可以通过
qDebug() << myPixmap->size();查看加载图片后的实际尺寸,验证线条坐标是否在范围内。
内容的提问来源于stack exchange,提问作者Steg
相关产品推荐
相关产品推荐

