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
  • 01 червня 2017 р. 04:13

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

Evgenii Legotckoi
  • 01 червня 2017 р. 12:29

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

АО
  • 13 березня 2020 р. 15:20

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

Evgenii Legotckoi
  • 13 березня 2020 р. 15:38

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

МЧ
  • 18 травня 2020 р. 00:12

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

Evgenii Legotckoi
  • 18 травня 2020 р. 13:31

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

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up
  • Останні коментарі
  • Evgenii Legotckoi
    16 квітня 2025 р. 17:08
    Благодарю за отзыв. И вам желаю всяческих успехов!
  • IscanderChe
    12 квітня 2025 р. 17:12
    Добрый день. Спасибо Вам за этот проект и отдельно за ответы на форуме, которые мне очень помогли в некоммерческих пет-проектах. Профессиональным программистом я так и не стал, но узнал мно…
  • AK
    01 квітня 2025 р. 11:41
    Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
  • Evgenii Legotckoi
    09 березня 2025 р. 21:02
    К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
  • VP
    09 березня 2025 р. 16:14
    Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…