Evgenii Legotckoi
20 марта 2016 г. 22:31

Qt/C++ - Урок 044. Сохранение объектов QGraphicsScene в файл векторной графики SVG

С помощью библиотеки Qt можно сохранять содержимое графической сцены QGraphicsScene в файлы векторной графики формата SVG, которые после без проблем открываются в таких редакторах, как CorelDraw. Предлагаю написать небольшое приложение, которое позволит сохранить содержимое графической сцены в файл формата SVG, а потом откроем его с помощью CorelDraw .

Структура проекта

  • SvgExample.pro - профайла проекта;
  • mainwindow.h - заголовочного файла главного окна приложения;
  • mainwindow.cpp - файла исходных кодов главного окна приложения, в котором и будет происходить всё действо;
  • mainwindow.ui - файл формы главного окна приложения;
  • main.cpp - основного стартового файла исходных кодов.

mainwindow.ui

В дизайнере интерфейсов набросаем кнопочку, которая будет открывать диалоговое окно, в котором выберем путь сохранения SVG файла. А также установим виджет QGraphicsView, в который будет помещена графическая сцена.

SvgExample.pro

В профайле проекта в обязательном порядке необходимо подключить модуль SVG , чтобы была возможность работать с классами векторной графики.

  1. #-------------------------------------------------
  2. #
  3. # Project created by QtCreator 2016-03-09T23:52:59
  4. #
  5. #-------------------------------------------------
  6.  
  7. QT += core gui svg
  8.  
  9. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
  10.  
  11. TARGET = SvgExample
  12. TEMPLATE = app
  13.  
  14.  
  15. SOURCES += main.cpp\
  16. mainwindow.cpp
  17.  
  18. HEADERS += mainwindow.h
  19.  
  20. FORMS += mainwindow.ui

main.cpp

Файл остается без изменений.

  1. #include "mainwindow.h"
  2. #include <QApplication>
  3.  
  4. int main(int argc, char *argv[])
  5. {
  6. QApplication a(argc, argv);
  7. MainWindow w;
  8. w.show();
  9.  
  10. return a.exec();
  11. }

mainwindow.h

Итак, в заголовочном файле главного окна приложения подключим библиотеки QGraphicsScene , QGraphicsRectItem, QSvgGenerator, QFileDialog и QPainter.

На графической будет создано два прямоугольника, которые необходимо будет сохранить в файл SVG. Сохранение будет производиться в слоте обработки нажатия кнопки, которая будет вызывать диалоговое окно для выбора пути сохранения SVG файла.

  1. #ifndef MAINWINDOW_H
  2. #define MAINWINDOW_H
  3.  
  4. #include <QMainWindow>
  5. #include <QGraphicsScene>
  6. #include <QGraphicsRectItem>
  7. #include <QSvgGenerator>
  8. #include <QFileDialog>
  9. #include <QPainter>
  10.  
  11. namespace Ui {
  12. class MainWindow;
  13. }
  14.  
  15. class MainWindow : public QMainWindow
  16. {
  17. Q_OBJECT
  18.  
  19. public:
  20. explicit MainWindow(QWidget *parent = 0);
  21. ~MainWindow();
  22.  
  23. private slots:
  24. void on_saveButton_clicked();
  25.  
  26. private:
  27. Ui::MainWindow *ui;
  28. QGraphicsScene *scene; // Графическая сцена
  29. QString path; // Путь сохранения файла
  30. };
  31.  
  32. #endif // MAINWINDOW_H

mainwindow.cpp

Для задания служебных параметров и отрисовки графических объектов с графической сцены используется объекта класса QSvgGenerator , но для передачи данных и непосредственной отрисовки в данный объект будет использоваться объекта класса QPainter , в который устанавливается целевой объект, в который будет производиться отрисовка с помощью метода begin(), а целью отрисовки будет непосредственно сам объект класса QSvgGenerator. Отрисовка будет произодиться с помощью метода графической сцены render(), через QPainter.

  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"
  3.  
  4. MainWindow::MainWindow(QWidget *parent) :
  5. QMainWindow(parent),
  6. ui(new Ui::MainWindow)
  7. {
  8. ui->setupUi(this);
  9.  
  10. scene = new QGraphicsScene();
  11. ui->graphicsView->setScene(scene);
  12. scene->setSceneRect(0,0,400,400);
  13.  
  14. // Создаём первый красный прямоугольник на графической сцене
  15. QGraphicsRectItem *rect1 = new QGraphicsRectItem();
  16. rect1->setRect(10,50,100,50);
  17. rect1->setBrush(QBrush(Qt::red));
  18. rect1->setPen(QPen(QBrush(Qt::black),2));
  19. scene->addItem(rect1);
  20.  
  21. // И создаём второй синий прямоугольник на графической сцене
  22. QGraphicsRectItem *rect2 = new QGraphicsRectItem();
  23. rect2->setRect(150,100,115,75);
  24. rect2->setBrush(QBrush(Qt::blue));
  25. rect2->setPen(QPen(QBrush(Qt::black),2));
  26. scene->addItem(rect2);
  27. }
  28.  
  29. MainWindow::~MainWindow()
  30. {
  31. delete ui;
  32. }
  33.  
  34. void MainWindow::on_saveButton_clicked()
  35. {
  36. // Заберём путь к файлу и его имененем, который будем создавать
  37. QString newPath = QFileDialog::getSaveFileName(this, trUtf8("Save SVG"),
  38. path, tr("SVG files (*.svg)"));
  39.  
  40. if (newPath.isEmpty())
  41. return;
  42.  
  43. path = newPath;
  44.  
  45. QSvgGenerator generator; // Создаём объект генератора файла
  46. generator.setFileName(path); // Устанавливаем путь к файлу, куда будет сохраняться векторная графика
  47. generator.setSize(QSize(scene->width(), scene->height())); // Устанавливаем размеры рабочей области документа в миллиметрах
  48. generator.setViewBox(QRect(0, 0, scene->width(), scene->height())); // Устанавливаем рабочую область в координатах
  49. generator.setTitle(trUtf8("SVG Example")); // Титульное название документа
  50. generator.setDescription(trUtf8("File created by SVG Example")); // Описание документа
  51.  
  52. // С помощью класса QPainter
  53. QPainter painter;
  54. painter.begin(&generator); // Устанавливаем устройство/объект в котором будем производить отрисовку
  55. scene->render(&painter); // Отрисовываем содержимое сцены с помощью painter в целевое устройство/объект
  56. painter.end(); // Заканчиваем отрисовку
  57.  
  58. // По окончанию отрисовки получим векторный файл с содержимым графической сцены
  59. }

Итог

В результате выполнения данного программного кода вы получите SVG файл, который успешно откроется в CorelDraw.

  1. SvgReader на Qt. Восстановление данных из файла SVG в QGraphicsScene

Видеоурок

Вам это нравится? Поделитесь в социальных сетях!

N
  • 1 июня 2017 г. 4:13

Добрый вечер. Встал вопрос. Каким образом сохранить координаты объектов, потому что в следующем уроке объекты на сцене будут находиться все в одном месте из которого их еще придется перетаскивать

Evgenii Legotckoi
  • 1 июня 2017 г. 12:29

Координаты объектов в данном случае нормально сохраняются. В конце статьи есть урок по восстановлению данных из SVG файла, изучите его. Там показано, как расположить объекты на графической сцене во время восстановления данных.

АО
  • 13 марта 2020 г. 15:20

Здравствуйте!
Как можно добавить текст туда?
Хочу попробовать нарисовать граф и обозначить вершины с дугами.

Evgenii Legotckoi
  • 13 марта 2020 г. 15:38

Добрый день.
Текст можно добавить на графическубюю сцену с помощью QGraphicsTextItem.

МЧ
  • 18 мая 2020 г. 0:12

Добрый день!
А не подскажете как можно сохранить фон, если это моя собственная картинка? При сохранении просто однотонного фона, не картинки все работает хорошо.

Evgenii Legotckoi
  • 18 мая 2020 г. 13:31

Добрый день.
Не подскажу. Могу только направить. Для это нужно в каком-нибудь популярном svg редакторе смотреть, как будет сохраняться ихображение, и потом попытаться повторить тоже самое средствами Qt.
Вполне возможно, что изображение там или отдельно будет сохраняться или будет как-то встраиваться в SVG файл.

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь