QGraphicsView défilement et mise à l'échelle de l'image / culture
-
21-09-2019 - |
Question
Je voudrais avoir une image de fond dans mon QGraphicsView qui est toujours mis à l'échelle (et recadrée si nécessaire) à la taille de la fenêtre, sans barres de défilement et sans défilement avec le clavier et la souris. L'exemple ci-dessous est ce que je fais à l'échelle et recadrer une image dans la fenêtre, mais j'utilise des valeurs aléatoires pour la culture qui sont tirés de la aether. Je voudrais une solution logique?
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
scene = new QGraphicsScene(this);
ui->graphicsView->resize(800, 427);
// MainWindow is 800x480, GraphicsView is 800x427. I want an image that
// is the size of the graphicsView.
ui->graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
// the graphicsView still scrolls if the image is too large, but
// displays no scrollbars. I would like it not to scroll (I want to
// add a scrolling widget into the QGraphicsScene later, on top of
// the background image.)
QPixmap *backgroundPixmap = new QPixmap(":/Valentino_Bar_Prague.jpg");
QPixmap sized = backgroundPixmap->scaled(
QSize(ui->graphicsView->width(),
ui->graphicsView->height()),
Qt::KeepAspectRatioByExpanding); // This scales the image too tall
QImage sizedImage = QImage(sized.toImage());
QImage sizedCroppedImage = QImage(sizedImage.copy(0,0,
(ui->graphicsView->width() - 1.5),
(ui->graphicsView->height() + 19)));
// so I try to crop using copy(), and I have to use these values
// and I am unsure why.
QGraphicsPixmapItem *sizedBackground = scene->addPixmap(
QPixmap::fromImage(sizedCroppedImage));
sizedBackground->setZValue(1);
ui->graphicsView->setScene(this->scene);
}
Je voudrais savoir un moyen d'échelle et recadrer une image à la taille de la QGraphicsView qui fonctionnera même quand je le remets à la côte QGraphicsView. Où sont les 1,5 et 19 provenant?
EDIT; J'ai aussi tenté d'utiliser setBackgroundBrush, mais je reçois un fond carrelé, même en utilisant la mise à l'échelle / recadrée QImage / QPixmap.
EDIT; Ma solution a été jusqu'à présent de passer outre drawBackground () pour obtenir le résultat que je voulais, mais cela ne fonctionne toujours me aider à ne pas apprendre à la taille d'une image à la taille de la fenêtre d'un QGraphicsView. Toute autre réponse serait grandement apprécié.
void CustomGraphicsView::drawBackground( QPainter * painter, const QRectF & rect )
{
qDebug() << "background rect: " << rect << endl;
QPixmap *backgroundPixmap = new QPixmap(":/Valentino_Bar_Prague.jpg");
QPixmap sized = backgroundPixmap->scaled(QSize(rect.width(), rect.height()), Qt::KeepAspectRatioByExpanding);
painter->drawPixmap(rect, sized, QRect(0.0, 0.0, sized.width(), sized.height()));
}
La solution
Vous voulez sceneRect
non seulement width
et height
. Pour la mise à l'échelle sur Redimensionner vous souhaitez connecter une fente pour sceneRectChanged
afin que vous puissiez redimensionner l'image à chaque fois que la scène change de taille.
Vous pouvez obtenir un QGraphicsView
avec une surchargée updateSceneRect
qui change la taille de l'image, ou mieux encore, juste passer outre drawBackground
.
Autres conseils
J'ai trouvé ui->graphicsView->viewport()->size()
pour obtenir la taille de la fenêtre. Fonctionne uniquement après le widget a été dessiné bien.
Le QGraphicsView::fitInView
fait exactement cela. Selon la documentation, il est souvent mis dans un resizeEvent
. L'utilisation sceneRects
rend toute forme de scène dans la vue:
void CustomGraphicsView::resizeEvent(QResizeEvent *)
{
this->fitInView(this->sceneRect());
}