Qt fitInView和调整大小

时间:2013-07-22 14:15:26

标签: c++ qt

我正在尝试制作一个宽度与位于窗口中心相同宽度的QGraphicsView

我在Qt Designer中创建了一个普通的QGraphicsView并设置了最小尺寸,添加了一些计算,将QGraphicsView置于主窗口的中心,并设置与高度相同的宽度。它仅使用setGeometry。比我创建一个只有一个很长矩形的QGraphicsScene。我希望图形场景适合查看,所以我使用了QGraphicsView::fitInView。一切正常,但问题在于调整窗口大小。

当我增加窗口的高度和宽度时,一切都很好。 QGraphicsView有新职位和新职位。当我只减少窗口大小的一部分时,一切仍然正常。但是(最后)当我将窗口的大小减小到可能的最小值时,一切都会中断。视图中的矩形具有正确的宽度(与没有调整大小相同,我用尺子测量它:)),但是创建了一个新的边距并且QGraphicsView没有定位并且尺寸合适(所以它不是只有保证金,但也许setGeometry没有效果。)

我注意到,在使用QGraphicsView::fitInView之前拨打setGeometry时会发生同样的事情。

让我发疯,请帮助!

以下是一些代码:

void MainWindow::resizeEvent(QResizeEvent *e)
{
    int h = e->size().height(),
        w = e->size().width(),
        s;

    if(w > h) s = h-120;
    else s = w-120;

    ui->board->setGeometry((w-s)/2,(h-s)/2,s,s);

    int scaleWidth = ui->board->scene()->width(),
        scaleHeight = ui->board->scene()->height();

    ui->board->fitInView(QRectF(0, 0, scaleWidth, scaleHeight), Qt::KeepAspectRatio);

}

以下是QGraphicsView发生的事情的图像,矩形为红色,视图为蓝色:

this is OK this is broken

2 个答案:

答案 0 :(得分:8)

我试图将QGraphicsView::fitInViewQt::KeepAspectRatio,一起使用,并遇到了类似的问题。
我发现这个答案很有用:

How to anchor QGraphicsView to a special point on a scene?

似乎关键是手动设置场景的边界矩形。以下代码对我有用:

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // Set up graphics view
    scene = new QGraphicsScene(this);
    drawMyWidget();
    scene->setSceneRect(-1.25, -1.25, 2.5, 2.5);    // your scene's bounding rect here...
    ui->graphicsView->setScene(scene);
    ui->graphicsView->show();
}

void MainWindow::resizeEvent(QResizeEvent *) {
    QRectF bounds = scene->itemsBoundingRect();
    bounds.setWidth(bounds.width()*0.9);         // to tighten-up margins
    bounds.setHeight(bounds.height()*0.9);       // same as above
    ui->graphicsView->fitInView(bounds, Qt::KeepAspectRatio);
    ui->graphicsView->centerOn(0, 0);
}

答案 1 :(得分:0)

我需要在DialogForm中做同样的事情...

我这样定义了Class标头

#ifndef MAP_H
#define MAP_H

#include <QDebug>
#include <QDialog>
#include <QImage>
#include <QGraphicsPixmapItem>
namespace Ui {
class Map;
}

class Map : public QDialog
{
    Q_OBJECT

public:
    explicit Map(QWidget *parent = nullptr);
    ~Map();

private:
    Ui::Map *ui;
    QPixmap *m;         // This will load the Original Image
    QGraphicsScene* scene;  // This is the object passed to the Graphics Viewer
    QPixmap *scaledImage;  // This is the Scaled Image. It is created each resize from the Original Image (m)
    void resizeEvent(QResizeEvent *);

};

#endif // MAP_H

对话框表单非常简单,看起来像这样,它是带有OK / Cancel按钮的GraphicsView。

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Map</class>
 <widget class="QDialog" name="Map">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>675</width>
    <height>486</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Dialog</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout">
   <item>
    <widget class="QGraphicsView" name="graphicsView"/>
   </item>
   <item>
    <widget class="QDialogButtonBox" name="buttonBox">
     <property name="orientation">
      <enum>Qt::Horizontal</enum>
     </property>
     <property name="standardButtons">
      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
     </property>
    </widget>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections>
  <connection>
   <sender>buttonBox</sender>
   <signal>accepted()</signal>
   <receiver>Map</receiver>
   <slot>accept()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>248</x>
     <y>254</y>
    </hint>
    <hint type="destinationlabel">
     <x>157</x>
     <y>274</y>
    </hint>
   </hints>
  </connection>
  <connection>
   <sender>buttonBox</sender>
   <signal>rejected()</signal>
   <receiver>Map</receiver>
   <slot>reject()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>316</x>
     <y>260</y>
    </hint>
    <hint type="destinationlabel">
     <x>286</x>
     <y>274</y>
    </hint>
   </hints>
  </connection>
 </connections>
</ui>

该类的实现是这样的。...

#include "map.h"
#include "ui_map.h"

Map::Map(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Map)
{
    ui->setupUi(this);
    scene = new QGraphicsScene();
    QWidget::setMouseTracking(true);

    m = new QPixmap ("/usr/local/share/pixmaps/gpredict/maps/nasa-topo_1600.jpg");
}

Map::~Map()
{
    delete m;
    delete scene;
    delete ui;
}

void Map::resizeEvent(QResizeEvent *)
{
    qInfo() << "Resize event occurred";
    QSize gvs  = ui->graphicsView->size();
    QSize mvs  =  m->size();   // Just for interest

    qInfo() << "About to scale";
    qInfo() << "mvs is " << mvs;
    qInfo() << "gvs is " << gvs;
    QPixmap scaled_img = m->scaled(gvs, Qt::IgnoreAspectRatio);

    scene = new QGraphicsScene(this);
    scene->addPixmap(scaled_img);
    ui->graphicsView->setScene(scene);


}

现在,无论何时更改dialogForm的大小,图像的大小都将被调整。 (原始)从原始图像中重新采样,否则可能会降低图像质量。

我只是进入QT编程的第二天-试图弄清楚它是如何连接的,但是我希望这对某人有帮助。