QGraphicsScene::fitInView() 仅适用于调整大小
Posted
技术标签:
【中文标题】QGraphicsScene::fitInView() 仅适用于调整大小【英文标题】:QGraphicsScene::fitInView() only works on resizing 【发布时间】:2016-02-09 12:47:59 【问题描述】:我有一个在静态地图上进行的游戏。我想在 QGraphicsView::drawBackground() 中绘制地图。
一切看起来都很好。除非我调整窗口大小,否则不会绘制任何内容...我认为这与 QGraphicsScene::fitInView()
或相关内容有关...
我的 mapscene.cpp
#include "mapscene.h"
#include <qpainter.h>
#include <iostream>
static const float WIDTH = 800.f;
static const float HEIGHT = 480.f;
static const float _map[][2] =
0, 0 ,
1, 1 ,
// 1, 0 , // TEMP: coordinates of map
// 0, 1 ,
// 0, 0 ,
;
MapScene::MapScene() : QGraphicsScene(0, 0, WIDTH, HEIGHT)
mapPath.moveTo(_map[0][0], _map[0][0]);
int len = sizeof(_map)/sizeof(float)/2;
std::cout << len << std::endl;
for(int i = 1; i < len; i++)
mapPath.lineTo(QPointF(_map[i][0]*WIDTH, _map[i][1]*HEIGHT));
void MapScene::drawBackground(QPainter *painter, const QRectF &)
std::cout << "draw background" << std::endl;
painter->drawPath(mapPath);
我的 mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <iostream>
#include "mapscene.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow)
ui->setupUi(this);
MapScene *scene = new MapScene();
ui->graphicsView->setScene(scene);
resizeEvent(0);
void MainWindow::resizeEvent(QResizeEvent *)
QRectF bounds = ui->graphicsView->scene()->sceneRect();
ui->graphicsView->fitInView(bounds, Qt::KeepAspectRatio);
ui->graphicsView->centerOn(bounds.center());
std::cout << "resize - scene rect: " << ui->graphicsView->sceneRect().width() << " x " << ui->graphicsView->sceneRect().height() << std::endl;
MainWindow::~MainWindow()
delete ui;
我使用的是 Qt 5.5.1 (Ubuntu)。
编辑:我已按照@LogicStuff 的建议将\n
更改为std::endl
,现在消息被打印出来,所以drawBackground()
正在 被调用。问题似乎出在QGraphicsView::fitInView()
和QGraphicsView::centerOn()
上。我已经相应地更改了帖子。
【问题讨论】:
【参考方案1】:问题是在实际显示小部件之前不应调用ui->graphicsView->fitInView(bounds, Qt::KeepAspectRatio);
:
https://***.com/a/17085612/2680707
【讨论】:
【参考方案2】:一个问题是MainWindow::drawBackground
中的std::cout << "draw background\n";
不会刷新std::cout
。另一方面,std::cout
因std::endl
而被刷新到MainWindow::resizeEvent
。
使用std::endl
或\n
和std::flush
。
【讨论】:
哦,谢谢。我不知道std::endl
和\n
之间有区别。现在消息被打印出来了,所以至少我知道问题不是因为 paintBackground()
没有被调用...【参考方案3】:
由于大多数情况下背景不会改变,因此默认情况下会使用 QGraphicsView::CacheBackground
对其进行缓存。你有两个选择:
-
使用
view.setCacheMode(QGraphicsView::CacheNone);
,但它可能会降低性能
每次需要时在背景层上使用invalidate(const QRectF & rect = QRectF(), SceneLayers layers = AllLayers)
。
即使第二个实现起来有点棘手,出于性能和 CPU 懒惰的考虑,我还是推荐它。
【讨论】:
不必对构造函数强制重绘。但是,唉,我做了,但仍然什么也没做......以上是关于QGraphicsScene::fitInView() 仅适用于调整大小的主要内容,如果未能解决你的问题,请参考以下文章