3

我正在尝试制作一个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,矩形是红色的,视图是蓝色的:

还行吧 这已破了

4

2 回答 2

10

我试图使用QGraphicsView::fitInViewQt::KeepAspectRatio,遇到类似的问题。
我发现这个答案很有帮助:

如何将 QGraphicsView 锚定到场景上的特殊点?

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

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);
}
于 2013-09-07T10:04:17.690 回答
0

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

我像这样定义了类头

#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

Dialog Form 非常简单,看起来像这样,它是一个带有 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 的大小,就会调整 Image 的大小。它(重要地)从原始图像中重新采样,否则可能会损失图像质量。

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

于 2020-08-26T07:57:29.407 回答