使用Qt::FastTransformation缩放QGraphicsPixmapItem时渲染异常
Qt Graphics View中QGraphicsPixmapItem缩放偏移问题求解
使用C++ Qt Graphics View框架在视图中显示图像及各类图形,缩放视图时发现:当图像宽/高与缩放因子为特定组合时,QGraphicsPixmapItem无法正常渲染,出现偏移问题。
以下是可在Qt5和Qt6中复现问题的最简代码:
#include <QApplication> #include <QGraphicsPixmapItem> #include <QGraphicsScene> #include <QGraphicsView> #include <QPixmap> #include <QVBoxLayout> QPixmap GetPixmap(int width, int height) { const QRgb pixelValues[] = { qRgb(100, 100, 100), qRgb(200, 200, 200) }; QImage image(width, height, QImage::Format::Format_ARGB32); for (int i = 0; i < width * height; ++i) { auto imgBits = reinterpret_cast<QRgb*>(image.bits()); imgBits[i] = pixelValues[i % 2]; } return QPixmap::fromImage(image); } int main(int argc, char* argv[]) { QApplication app(argc, argv); QWidget window; // 初始化包含图像和矩形的场景 QGraphicsScene* scene = new QGraphicsScene(&window); // 添加棋盘格图像(用于演示问题) const int imgWidth = 1001; const int imgHeight = 10; auto pixmapItem = scene->addPixmap(GetPixmap(imgWidth, imgHeight)); // 取消注释该行会让图像变模糊,但偏移问题消失 //pixmapItem->setTransformationMode(Qt::SmoothTransformation); // 添加红色小矩形 QPen smallRecPen(Qt::red); smallRecPen.setCosmetic(true); for (int i = 0; i < imgWidth; ++i) { scene->addRect(i, 0, 1, 1, smallRecPen); scene->addRect(i, 1, 1, 1, smallRecPen); } // 添加与图像尺寸一致的绿色大矩形 QPen bigRecPen(Qt::green); bigRecPen.setCosmetic(true); scene->addRect(0, 0, imgWidth, imgHeight, bigRecPen); // 初始化视图 QGraphicsView* view = new QGraphicsView(&window); //view->setOptimizationFlags(QGraphicsView::OptimizationFlag::DontAdjustForAntialiasing); // 无效果 //view->setCacheMode(QGraphicsView::CacheBackground); // 无效果 view->setScene(scene); // 设置缩放因子 const double armfulZoomFactor = 30.0; // 这类异常因子有很多,具体值和图像尺寸相关,暂未发现规律 view->setTransform(QTransform(armfulZoomFactor, 0.0, 0.0, 0.0, armfulZoomFactor, 0.0, 0.0, 0.0, 1.0)); QVBoxLayout* layout = new QVBoxLayout(&window); layout->addWidget(view); window.showMaximized(); app.exec(); }
运行上述代码后会出现偏移问题(见配图)。
问题表现随图像尺寸和缩放因子的不同而变化:
- 示例中部分像素列宽度为31像素而非预期的30像素,导致越往右偏移越大,但小红矩形均保持30像素宽度正常显示,暂未找到异常列的规律(示例中为第69、204列等)。
- 部分理论上的精确缩放值会出问题,部分浮点缩放值却能正常工作,测试示例如下:
| 图像宽度 | 缩放值 | 状态 |
|---|---|---|
| 1001 | 30.0 | 异常 |
| 1001 | 30.3 | 严重异常 |
| 1001 | 67.6 | 正常 |
| 2001 | 30.0 | 正常 |
| 2001 | 30.3 | 正常 |
其他测试情况:
- 垂直方向也存在相同问题
- 尝试设置optimizationFlag、CacheBackground等均无效果
- 尝试单独缩放Item而非视图,结果相同
- 尝试通过构造函数创建Item,问题依旧
请问操作是否有误?能否提供解决建议?
内容的提问来源于stack exchange,提问作者user1159845
相关产品推荐
相关产品推荐

