Нужен полный аналог setScaledContents(true), как у QLabel, но только для QGraphicsView

172
30 апреля 2019, 23:00

Мне пришлось переписать связку QLabel-QPixmap на связку QGraphicsView-QGraphicsScene-QGraphicsPixmapItem-QPixmap. И вышло как-то совсем не очень.

Раньше было так:

void MainWindow::slotConstructWaterBodies(const QString& mapName, const QString& mapImagePath)
{   
    ui->mylabel->setPixmap(mapImagePath);
    /*Прочий код*/
}
void MainWindow::resizeEvent(QResizeEvent *event)
{
    adjustWidgetSize();    
    QMainWindow::resizeEvent(event);
}

Задает фиксированный размер виджета по ширине для сохранения пропорций картинки внутри него:

void MainWindow::adjustWidgetSize()
{
    int widthCurrentPixMap = 1;
    int heightCurrentPixMap = 1;
    if(pixPtr_) {
        widthCurrentPixMap = pixPtr_->width();
        heightCurrentPixMap = pixPtr_->height();
    }
    const QSize pixmapSize(widthCurrentPixMap, heightCurrentPixMap);
    ui->mylabel->setFixedWidth(
        ui->centralWidget->height() * pixmapSize.width() / pixmapSize.height()
    );
}

Ну там еще конечно самое важное в самом дизайнере - чек бокс напротив ScaledContents.

Теперь же все усложняется, ибо никакого ScaledContents свойства у QGraphicsView, к огромному сожалению, не имеется :

void MainWindow::slotConstructWaterBodies(const QString& mapName, const QString& mapImagePath)
{   
    QPixmap *pixmap = new QPixmap(mapImagePath);
    pixPtr_ = pixmap;
    QGraphicsScene *scene = new QGraphicsScene;
    QGraphicsPixmapItem *item = new QGraphicsPixmapItem(*pixPtr_);
    item->setTransformationMode(Qt::SmoothTransformation);
    scene->addItem(item);
    ui->graphicsViewMap->setScene(scene);
    ui->graphicsViewMap->fitInView(scene->sceneRect(), Qt::IgnoreAspectRatio);
    /*Прочий код*/
}
void MainWindow::resizeEvent(QResizeEvent *event)
{
    adjustWidgetSize();    
    adjustScaledPixmap();
    QMainWindow::resizeEvent(event);
}

Задает фиксированный размер виджета по ширине для сохранения пропорций картинки внутри него:

void MainWindow::adjustWidgetSize()
{
    int widthCurrentPixMap = 1;
    int heightCurrentPixMap = 1;
    if(pixPtr_) {
        widthCurrentPixMap = pixPtr_->width();
        heightCurrentPixMap = pixPtr_->height();
    }
    const QSize pixmapSize(widthCurrentPixMap, heightCurrentPixMap);
    ui->graphicsViewMap->setFixedWidth(
        ui->centralWidget->height() * pixmapSize.width() / pixmapSize.height()
    );
}
void MainWindow::adjustScaledPixmap()
{
    QGraphicsScene *scene = new QGraphicsScene;
    QGraphicsPixmapItem *item = new QGraphicsPixmapItem(*pixPtr_);
    item->setTransformationMode(Qt::SmoothTransformation);
    scene->addItem(item);
    ui->graphicsViewMap->setScene(scene);
    ui->graphicsViewMap->fitInView(scene->sceneRect(), Qt::IgnoreAspectRatio);
}

Но при этом сильно шершавит изображение до такой степени, что текст на нем становится еле читабельным. Никакие Qt::SmoothTransformation совершенно не помогают. Да еще и scale по каким-то причинам более-менее нормально отрабатывает лишь когда срабатывает resizeEvent, т.е. при первом запуске окна, если оно не на весь экран (когда на весь экран, то почему-то срабатывает - а на весь или не на весь это зависит от чтения из QSettings), то изображение почему-то очень мелкое по центру почти пустого виджета.

Еще, между изображением и виджетом QGraphicsView появляется белая мелкая рамка и она может становится больше в зависимости от размера открытого окна.

Ну и кроме того, мне теперь приходится хранить в классе указатель на динамически созданный QPixmap, т.к. QGraphicsPixmapItem зачем-то требует текущий pixmap, а ui->graphicsViewMap->grab() его не устраивает.

Можно как-то получить результат в стиле QLabel?

READ ALSO
Преобразовать double в RGB(Qcolor)

Преобразовать double в RGB(Qcolor)

Необходимо значение double преобразовать в цвет, чтобы потом использовать в функции SetPixel(x,y,qRGB)Есть такой код преобразования, но по-моему он не работает

161
Перегрузка оператора [] C++

Перегрузка оператора [] C++

У меня есть односвязный списокВ нем надо перегрузить [] так, чтоб был доступ к элементу в заданной позиции

173
Как изменить название окна программы в Qt

Как изменить название окна программы в Qt

Столкнулся с такой проблемойХочу поменять название окна программы с MainWindow на своё

216