Я делаю небольшую программу черчения с группой студентов, мы используем Qt QGraphicsScene на QGraphicsView, чтобы позволить пользователю наносить пользовательские точки на определенных позициях (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 (я думаю) и выяснить значение радиуса + шрифтразмер, который мы должны использовать для точки и текста, так чтоони остаются одинаковыми, независимо от размера сцены.
РЕДАКТИРОВАТЬ: Это НОВЫЙ код (в соответствии с решением 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), который установит Position в x, y, который мы передаем в AddPoint (x, y).Точки теперь сохраняют один и тот же размер независимо от размера Сцены, и на них будут показаны все созданные Точки сразу без полос прокрутки или чего-либо еще.
Спасибо!