You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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列等)。
  • 部分理论上的精确缩放值会出问题,部分浮点缩放值却能正常工作,测试示例如下:
图像宽度缩放值状态
100130.0异常
100130.3严重异常
100167.6正常
200130.0正常
200130.3正常

其他测试情况:

  • 垂直方向也存在相同问题
  • 尝试设置optimizationFlag、CacheBackground等均无效果
  • 尝试单独缩放Item而非视图,结果相同
  • 尝试通过构造函数创建Item,问题依旧

请问操作是否有误?能否提供解决建议?

内容的提问来源于stack exchange,提问作者user1159845

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 01:11:16