QGRAPHICSVIEW ROLOLING E SCALING/CRIPPURO DE IMAGEM
-
21-09-2019 - |
Pergunta
Eu gostaria de ter uma imagem de fundo no meu qgraphicsView que sempre é escalado (e cortado, se necessário) para o tamanho da viewport, sem barras de rolagem e sem rolar com o teclado e o mouse. O exemplo abaixo é o que estou fazendo para dimensionar e cortar uma imagem na viewport, mas estou usando valores aleatórios para o corte que são retirados do aether. Queria uma solução lógica?
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);
}
Gostaria de saber uma maneira de dimensionar e cortar uma imagem para o tamanho do QGraphicsView que funcionará mesmo quando eu redimensionar o QGraphicsView. De onde vêm os 1.5 e 19?
EDITAR; Eu também tentei usar o SsentbackgroundBrush, mas recebo um fundo de azulejos, mesmo ao usar o QIMAGE/QPIXMAP SCALED/CRUPPED.
EDITAR; Até agora, minha solução foi substituir o Drawbackground () para obter o resultado que eu queria, mas isso ainda não me ajuda a aprender a dimensionar uma imagem para o tamanho da viewport de um QGraphicsView. Quaisquer respostas adicionais seriam muito apreciadas.
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()));
}
Solução
Você quer sceneRect
não apenas width
e height
. Para a escala em redimensionamento, você deseja conectar um slot a sceneRectChanged
Assim, você pode redimensionar a imagem sempre que a cena mudar de tamanho.
Ou você pode derivar um QGraphicsView
com um substituto updateSceneRect
Isso muda o tamanho da imagem, ou melhor ainda, apenas substitua drawBackground
.
Outras dicas
eu encontrei ui->graphicsView->viewport()->size()
Para obter o tamanho da viewport. Funciona apenas depois que o widget foi desenhado.
o QGraphicsView::fitInView
faz exatamente isso. De acordo com a documentação, é comumente colocado em um resizeEvent
. Usando sceneRects
faz a cena inteira se encaixar na vista:
void CustomGraphicsView::resizeEvent(QResizeEvent *)
{
this->fitInView(this->sceneRect());
}