【发布时间】:2018-06-02 01:50:55
【问题描述】:
我正在和一群学生一起做一个小绘图程序,我们在 QGraphicsView 上使用 Qt 的 QGraphicsScene 让用户在特定位置 (x , y) 上绘制自定义点,每个点上面都必须有一个文本.
这是负责将点添加到场景的函数:
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
*/
}
所以实现会是这样的:
AddPoint(0 , 0 , "P1"); // Point 1
AddPoint(50 , 100 , "P2"); // Point 2
AddPoint(100 , 0 , "P3"); // Point 3
这将导致:
我们正在使用:
ui->graphicsView->fitInView(ui->graphicsView->scene()->sceneRect() , Qt::KeepAspectRatio);
确保 QGraphicsView 只显示可见的内容(非常重要)。
所以这里的问题是,如果我们要使绘图更大,例如:
AddPoint(0 , 0 , "P1");
AddPoint(0 , 1000 , "P2"); // y = 1000
这将绘制一条很长的线,这将使我们创建的点 + 文本变得非常小,甚至无法看到:
因此,我们需要以某种方式计算 SceneRect(我认为)并找出我们应该为 Point 和 Text 使用的半径值 + 字体大小,以便无论场景大小如何,它们都保持相同的大小。
编辑: 这是新代码(根据 vcloarec 的解决方案):
GraphicsWindow.h(QGraphicsView 子类):
#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;
}
此代码根据固定比例缩放点,但仍会导致滚动条,这是我们必须解决的问题。 不知何故,它忽略了 fitInView() ,或者它确实适合它,但是当调整点的大小时,它会调整 SceneRect 或其他东西的大小
结果如下:
PS : 我们将 QGraphicsView 子类化了,因为稍后我们将需要 MouseEvents 和其他东西。
编辑:由 vcloarec 解决: 解决方案是在 (-0.5 , -0.5) 处插入点,然后 setPose(x , y) 将位置设置为 x , y 我们传递给 AddPoint(x , y)。 无论场景的大小如何,点现在都保持相同的大小,并且它将显示一次创建的所有点,而没有任何滚动条或任何东西。
谢谢!
【问题讨论】: