【问题标题】:Is there QLabel::setScaledContents equivalent function for QGraphicsScene in Qt?Qt 中的 QGraphicsScene 是否有 QLabel::setScaledContents 等效函数?
【发布时间】:2019-10-20 23:06:04
【问题描述】:

我正在使用 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));
    }

}

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

【问题讨论】:

    标签: c++ qt scale qgraphicsview qgraphicsscene


    【解决方案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); });
    

    【讨论】:

    • 感谢您提供的代码。你能解释一下创建一个新类的意义吗?
    • 这就是我在示例中所做的:我创建了一个类 GraphicsScene,它继承自 QGraphicsScene
    猜你喜欢
    • 1970-01-01
    • 2021-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-10
    • 2019-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多