Im doing a little Plotting program with a group of students , we are using Qt's QGraphicsScene on a QGraphicsView to let the user plot custom Points on Specific Positions (x , y) , each point has to have a text on top of it.
Here is the function responsible for adding Points to the Scene :
void MainWindow::AddPoint(float x, float y, QString name)
{
y = y * -1; // To Flip Y-Axis
float Radius = 1; // Point's (Eclipse) Radius
QGraphicsItem *Point = p_Scene->addEllipse(x , y , Radius , Radius , QPen(QColor(Qt::red)) , QBrush(QColor(Qt::red))); // Creates a Red Colored Point on the given Coordinates (x , y)
/*
QGraphicsTextItem *Text = p_Scene->addText(name); // Creates a Text
Text->setDefaultTextColor(QColor(Qt::red)); // Sets Text's Color to Red
Text->setFont(QFont("Courier New" , 4)); // Sets Text's Font Size
Text->setPos(x , y - 10); // Set Text's Position (On top of the Point)
ui->graphicsView->setScene(p_Scene); // Adds Text to the Scene
*/
}
so the Implementation would be like :
AddPoint(0 , 0 , "P1"); // Point 1
AddPoint(50 , 100 , "P2"); // Point 2
AddPoint(100 , 0 , "P3"); // Point 3
This will results in :
We are using :
ui->graphicsView->fitInView(ui->graphicsView->scene()->sceneRect() , Qt::KeepAspectRatio);
to make sure that QGraphicsView shows only whats visible (pretty important).
so the problem here is , if we were to make the drawing larger , say for example :
AddPoint(0 , 0 , "P1");
AddPoint(0 , 1000 , "P2"); // y = 1000
This will draw a very long line which will make the Points + Text we created so small that it cant even be seen :
So what we need here is to somehow calculate the SceneRect (i think) and find out the radius value + font size that we should use for both the Point and the Text so they stay the same size regardless of the Scene's Size.
EDIT : This is the NEW code (according to vcloarec's solution) :
GraphicsWindow.h (QGraphicsView Subclass) :
#ifndef GRAPHICSVIEW_H
#define GRAPHICSVIEW_H
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QDebug>
class GraphicsView : public QGraphicsView
{
Q_OBJECT
public:
explicit GraphicsView(QWidget *parent = 0);
void AddPoint(float x , float y , QString name = "");
void resize();
private:
QGraphicsScene *p_Scene;
int p_SizeInView;
};
#endif // GRAPHICSVIEW_H
GraphicsWindow.cpp :
#include "GraphicsView.h"
GraphicsView::GraphicsView(QWidget *parent) : QGraphicsView(parent)
{
p_PointRadius = 0.0;
p_PointsLastN = 0;
p_SizeInView = 5;
p_Scene = new QGraphicsScene(this);
this->setScene(p_Scene);
}
void GraphicsView::AddPoint(float x, float y, QString name)
{
y = y * -1;
QGraphicsItem *_Point = p_Scene->addEllipse(x , y , 1 , 1 , QPen(QColor(Qt::red)) , QBrush(QColor(Qt::red)));
this->fitInView(scene()->sceneRect() , Qt::KeepAspectRatio);
resize();
}
void GraphicsView::resize()
{
qreal scale = p_SizeInView / this->transform().m11();
for(int i = 0; i < this->scene()->items().count(); i++)
{
this->scene()->items().at(i)->setScale(scale);
}
}
MainWindow.cpp :
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->toolBar->addWidget(ui->ZoomUp_Button);
ui->toolBar->addWidget(ui->ZoomDown_Button);
setCentralWidget(ui->graphicsView);
ui->graphicsView->AddPoint(0 , 0);
ui->graphicsView->AddPoint(1000 , 0);
ui->graphicsView->AddPoint(1000 , 50);
ui->graphicsView->AddPoint(0 , 50);
}
MainWindow::~MainWindow()
{
delete ui;
}
This code scales the Points according to a fixed Scale but still results in Scrollbars which is something we have to solve. Somehow it ignores fitInView() , OR it does actually fit it but when the Points are resized it resizes the SceneRect or something
Here is the result :
PS : We subclassed QGraphicsView because we will need MouseEvents and other things later.
EDIT : Solved by vcloarec : The solution was to insert the Points at (-0.5 , -0.5) and than setPose(x , y) which will set the Position to the x , y we pass to the AddPoint(x , y). The Points now keep the same size regardless of the Scene's size , and it will show all the Points created at once without any scrollbars or anything.
Thank You !