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

标签 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));
    }

}

这样可以吗?我是否可以实现我想要的行为而不需要在每次上传操作时都创建新场景?

最佳答案

插入像素图时,您只需根据场景大小调整场景大小即可。

如果你定义一个继承自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); });

关于c++ - Qt 中的 QGraphicsScene 是否有 QLabel::setScaledContents 等效函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56460462/

相关文章:

c++ - 使用Qt录制系统声音

c++ - 在 C++ 中打开文件 - getline 在第二次迭代时失败

c++ - 将结构复制到新结构

C++ 错误 C3646、C2059 和 C2238 Visual Studio 2015(社区)

r - ggplot2 grid.export 绘图大小 SVG

CSS3 Scale 不适用于 Firefox 34.0.5 中的 <a>

html - Internet Explorer - 悬停时图像缩放出血

java - 生成部分排序的随机数字列表

c++ - 在qt中获取标签的鼠标点击位置

python - matplotlib 不导入 PyQt4、PyQt5 或 PySide