Qt中的QGraphicsScene是否有QLabel :: setScaledContents等效函数?

时间:2019-06-05 12:24:57

标签: c++ qt scale qgraphicsview qgraphicsscene

我正在使用QGraphicsView和QGraphicsScene显示上传的图像,然后在其上显示一些图形。我正在上传图片,如下所示:

void MeasuresWidget::on_openAction_triggered()
{
    QString fileName = QFileDialog::getOpenFileName(this,tr("Open File"), QDir::currentPath());
    if (!fileName.isEmpty())
    {
        QImage image(fileName);
        if (image.isNull())
        {
            QMessageBox::information(this, tr("Measures Application"), tr("Cannot load %1.").arg(fileName));
            return;
        }
        scene->clear();
        scene->addPixmap(QPixmap::fromImage(image).scaledToWidth(w, Qt::SmoothTransformation));
    }
}

我面临的问题是,如果我上传的图像小于之前上传的图像,则似乎有空白空间,即场景保持了前一张图像的大小(较大)并且更大比目前的我尝试在单个变量中保持场景的原始大小,并在每次上传操作中使用setSceneRect()

//in constructor
    originalRect = ui->graphicsView->rect();
//in upload action
    scene->setSceneRect(originalRect);

但是结果是场景的大小始终保持不变,并且如果它大于实际图像,则将其剪切。我以前使用QLabel显示图像,并且我使用过QLabel::setScaledContents()函数,它对我来说很好用。所以,我的问题是我可以使用QGraphicsScene实现相同的行为吗?

更新1: 如果我在每次上传操作中创建新场景,应用程序都会按照我想要的方式运行。现在的代码如下:

void MeasuresWidget::on_openAction_triggered()
{
    scene = new QGraphicsScene(this);
    ui->graphicsView->setScene(scene);
    QString fileName = QFileDialog::getOpenFileName(this,tr("Open File"), QDir::currentPath());
    if (!fileName.isEmpty())
    {
        QImage image(fileName);
        if (image.isNull())
        {
            QMessageBox::information(this, tr("Image Viewer"), tr("Cannot load %1.").arg(fileName));
            return;
        }
        scene->clear();
        scene->addPixmap(QPixmap::fromImage(image).scaledToWidth(w, Qt::SmoothTransformation));
    }

}

可以吗?无需在每次上传操作时都创建新场景就能实现我想要的行为吗?

1 个答案:

答案 0 :(得分:1)

在插入像素图时,您只需根据其大小来调整其大小即可。

如果您定义了一个继承自QGraphicsScene的新类,则可以轻松进行处理:

class GraphicsScene: public QGraphicsScene
{
public:
    GraphicsScene(QRect const& rect, QObject* parent=nullptr): QGraphicsScene(rect, parent),
        background(nullptr)
    {}

    QGraphicsPixmapItem *addPixmap(const QPixmap &pixmap)
    {
        // We already have a background. Remove it
        if (background)
        {
            removeItem(background);
            delete background;
        }
        background = QGraphicsScene::addPixmap(pixmap);
        // Move the pixmap
        background->setPos(0, 0);
        // Change the scene rect based on the size of the pixmap
        setSceneRect(background->boundingRect());
        return background;
    }
private:
    QGraphicsPixmapItem* background;
};
    GraphicsScene* scene = new GraphicsScene(QRect());
    QGraphicsView* view = new QGraphicsView();
    view->setScene(scene);
    view->show();

    QPixmap pix1(QSize(2000, 2000));
    pix1.fill(Qt::red);


    QPixmap pix2(QSize(100, 300));
    pix2.fill(Qt::green);

    // The scene will be 2000x2000
    QTimer::singleShot(1000, [=]() { scene->addPixmap(pix1); });
    // The scene will be 100x300
    QTimer::singleShot(10000, [=]() { scene->addPixmap(pix2); });