我正在使用 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/