前言
最近一直使用QGraphicsView框架在我的一个实际项目中,官方文档好多都没说清楚啊,有木有?!文档都翻光了,却还是有好多没明白。
一个令我恼火的bug就是,明明log打出来的每个Item的坐标都是预期的,但为什么最后结果不对呢?
我在视图中添加了一个直线项(QPoint(0,0),QPoint(100,100));
结果却是:
有的同行看到可能会一下指出,我没有设置QGraphicsScene的SceneRect,所以所有的元素默认显示。
是的,上面这个例子的确如此,但是即使我们设置了呢,结果却是这样:
直线项确实不居中了,但是端点也没有在左上角啊!下面,我们就来深入结合例子弄清楚这一些问题。
解决之道
先上demo代码,很简单,
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QGraphicsView>
#include<QGraphicsScene>
#include<QDebug>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void showView();//显示graphicsView的函数
private:
QGraphicsScene *graphicsScene;//scene声明
QGraphicsView *graphicsView;//view声明
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
graphicsScene = new QGraphicsScene(this);
graphicsView = new QGraphicsView(graphicsScene,this);
QSize window =this->size();
graphicsView->setFixedSize(this->width(),this->height());
graphicsScene->addLine(0,0,100,100);
}
void MainWindow::showView()
{
graphicsView->show();
}
MainWindow::~MainWindow()
{
delete ui;
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
qDebug() <<"line location:"<<"\n";
qDebug()<<"startPoint:" <<QPoint(0,0);
qDebug()<<"endPoint:" <<QPoint(100,100);
MainWindow w;
w.show();
w.showView();
return a.exec();
}
这份代码确实是QGraphicsScene和QGraphicsView的基本代码,并没有设置QGraphicsScene的sceneRect,所以结果也是大家可以预测的那样居中显示:
但是!很多时候框架中自认为很令人方便的设计一点都不利于我们开发,我们开发人员习惯的坐标系统是左上角为(0,0)的坐标系统!
于是,官方给出了解决方案:使用void setSceneRect(const QRectF & rect)控制sceneRect区域,这很人迷惑,就在我们这个例子中,我们想让scene左上角坐标是(0,0),是不是说只需要scene->setSceneRect(QRectF(0,0,W,H)就可以了呢?很遗憾的是,实验结果告诉我们不是:
我们在上面的mainwindow.cpp里面设置scenRect为(0,0,150,150)试试看!:
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
graphicsScene = new QGraphicsScene(this);
graphicsView = new QGraphicsView(graphicsScene,this);
QSize window =this->size();
graphicsView->setFixedSize(this->width(),this->height());
graphicsScene->setSceneRect(0,0,150,150);
graphicsScene->addLine(0,0,100,100);
}
void MainWindow::showView()
{
graphicsView->show();
}
MainWindow::~MainWindow()
{
delete ui;
}
结果是:
结果不是预期!
其实,正确的解决方案是setSceneRect(0,0,W,H);而且需要
- W>=static_cast< QWidget *>(graphicsScene->parent())->size().width()
- H>=static_cast< QWidget *>(graphicsScene->parent())->size().height()
看再次修改后的代码:
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QWidget>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
graphicsScene = new QGraphicsScene(this);
graphicsView = new QGraphicsView(graphicsScene,this);
QSize windowsize =this->size();
graphicsView->setFixedSize(this->width(),this->height());
graphicsScene->setSceneRect(0,0
,static_cast<QWidget *>(graphicsScene->parent())->size().width()
,static_cast<QWidget *>(graphicsScene->parent())->size().height());
graphicsScene->addLine(0,0,100,100);
}
void MainWindow::showView()
{
graphicsView->show();
}
MainWindow::~MainWindow()
{
delete ui;
}
运行结果:
下面有相应的工程下载:
戳我下载