问题
I am currently using QT to load images into a graphicsview scene. Essentially, I am looking for a way to be able to zoom in and out on the loaded image using a slider. The image loads successfully into the pane, but whatever I try to implement to zoom in / out, the image would disappear.
This is how it looks:
This is my implemented function, but the image disappears:
void MainWindow::on_horizontalSlider_valueChanged(int value)
{
float pool ;
if(value==0 )
pool=0.1;
else
pool = value*0.01;
scene->update();
ui->graphicsView->transform();
ui->graphicsView->scale(pool,pool);
}
This is how I'm loading the images:
void MainWindow::on_BrowseImages_clicked()
{
QString imagePath = QFileDialog::getOpenFileName(
this,
tr("Open File"),
"",
tr("Images (*.jpg *.jpeg *.png)" )
);
imageObject = new QImage();
imageObject->load(imagePath);
image = QPixmap::fromImage(*imageObject);
scene = new QGraphicsScene(this);
scene->addPixmap(image);
scene->setSceneRect(image.rect());
ui->graphicsView->setScene(scene);
//ui->graphicsView->fitInView(scene->sceneRect(),Qt::KeepAspectRatio);
}
回答1:
When scaling is applied to transformation it always scales around origin.
Scaling with a certain center (that is not the origin) means that the center has been translated to the origin before scaling.
This could be
v' = translateO→C(scale(translateC→O(v)))
or with matrix operations
v' = MtranslateO→C • Mscale • MtranslateC→O • v
However, the Grahics View Framework provides something where combining transformations is actually built-in by default:
- Every item provides its own local transformation.
- The transformation of a group item is applied to the child items as well forming something which can be imagined as a local coordinate system.
This in mind, I came up with the following MCVE where - translation to center is applied to the pixmap item - scaling is applied to a group item which becomes parent of the pixmap item.
testQGraphicsViewScaleItem.cc
:
// Qt header:
#include <QtWidgets>
// main application
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
// setup data
QGraphicsScene qGScene;
QGraphicsItemGroup qGItemGrp;
QImage qImgCat("cat.jpg");
QGraphicsPixmapItem qGItemImg(QPixmap::fromImage(qImgCat));
qGItemImg.setTransform(
QTransform().translate(-0.5 * qImgCat.width(), -0.5 * qImgCat.height()));
qGItemGrp.addToGroup(&qGItemImg);
qGScene.addItem(&qGItemGrp);
// setup GUI
QWidget qWinMain;
qWinMain.setWindowTitle("QGraphicsView - Scale Image");
QVBoxLayout qVBox;
QGraphicsView qGView;
qGView.setScene(&qGScene);
qVBox.addWidget(&qGView, 1);
QSlider qSlider(Qt::Horizontal);
qSlider.setRange(-100, 100);
qVBox.addWidget(&qSlider);
qWinMain.setLayout(&qVBox);
qWinMain.show();
// install signal handlers
auto scaleImg = [&](int value) {
const double exp = value * 0.01;
const double scl = pow(10.0, exp);
qGItemGrp.setTransform(QTransform().scale(scl, scl));
};
QObject::connect(&qSlider, &QSlider::valueChanged,
scaleImg);
// runtime loop
return app.exec();
}
and a qmake project file testQGraphicsViewScaleItem.pro
:
SOURCES = testQGraphicsViewScaleItem.cc
QT += widgets
Output:
来源:https://stackoverflow.com/questions/60240192/zooming-in-out-on-images-qt-c