- 1. Структура проекта
- 2. mainwindow.ui
- 3. SvgExample.pro
- 4. main.cpp
- 5. mainwindow.h
- 6. mainwindow.cpp
- 7. Підсумок
- 8. Відеоурок
За допомогою бібліотеки Qt можна зберігати вміст графічної сцени QGraphicsScene у файли векторної графіки формату SVG, які потім без проблем відкриваються в таких редакторах, як CorelDraw. Пропоную написати невелику програму, яка дозволить зберегти вміст графічної сцени у файл формату SVG, а потім відкриємо його за допомогою CorelDraw .
Структура проекта
- SvgExample.pro - профайл проекту;
- mainwindow.h - заголовного файлу головного вікна програми;
- mainwindow.cpp - файл вихідних кодів головного вікна програми, в якому і буде відбуватися все дійство;
- mainwindow.ui - файл форми головного вікна програми;
- main.cpp - основний стартовий файл вихідних кодів.
mainwindow.ui
У дизайнері інтерфейсів накидаємо кнопку, яка відкриватиме діалогове вікно, в якому виберемо шлях збереження SVG файлу. А також встановимо віджет QGraphicsView у який буде поміщена графічна сцена.
SvgExample.pro
У профайлі проекту обов'язково необхідно підключити модуль SVG , щоб була можливість працювати з класами векторної графіки.
#------------------------------------------------- # # Project created by QtCreator 2016-03-09T23:52:59 # #------------------------------------------------- QT += core gui svg greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = SvgExample TEMPLATE = app SOURCES += main.cpp\ mainwindow.cpp HEADERS += mainwindow.h FORMS += mainwindow.ui
main.cpp
Файл залишається без змін.
#include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
mainwindow.h
Отже, у заголовному файлі головного вікна програми підключимо бібліотеки QGraphicsScene , QGraphicsRectItem, QSvgGenerator, QFileDialog та QPainter.
На графічній буде створено два прямокутники, які необхідно зберегти в файл SVG. Збереження буде проводитися в слоті обробки натискання кнопки, яка буде викликати діалогове вікно для вибору шляху збереження SVG файлу.
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QGraphicsScene> #include <QGraphicsRectItem> #include <QSvgGenerator> #include <QFileDialog> #include <QPainter> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void on_saveButton_clicked(); private: Ui::MainWindow *ui; QGraphicsScene *scene; // Графическая сцена QString path; // Путь сохранения файла }; #endif // MAINWINDOW_H
mainwindow.cpp
Для завдання службових параметрів та відображення графічних об'єктів з графічної сцени використовується об'єкт класу QSvgGenerator , але для передачі даних та безпосереднього відображення в даний об'єкт буде використовуватися об'єкт класу QPainter , в який встановлюється цільовий об'єкт, в який буде здійснюватися малювання за допомогою методу begin(), а метою відображення буде безпосередньо сам об'єкт класу QSvgGenerator. Відображення буде відбутися за допомогою методу графічної сцени render(), через QPainter.
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); scene = new QGraphicsScene(); ui->graphicsView->setScene(scene); scene->setSceneRect(0,0,400,400); // Создаём первый красный прямоугольник на графической сцене QGraphicsRectItem *rect1 = new QGraphicsRectItem(); rect1->setRect(10,50,100,50); rect1->setBrush(QBrush(Qt::red)); rect1->setPen(QPen(QBrush(Qt::black),2)); scene->addItem(rect1); // И создаём второй синий прямоугольник на графической сцене QGraphicsRectItem *rect2 = new QGraphicsRectItem(); rect2->setRect(150,100,115,75); rect2->setBrush(QBrush(Qt::blue)); rect2->setPen(QPen(QBrush(Qt::black),2)); scene->addItem(rect2); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_saveButton_clicked() { // Заберём путь к файлу и его имененем, который будем создавать QString newPath = QFileDialog::getSaveFileName(this, trUtf8("Save SVG"), path, tr("SVG files (*.svg)")); if (newPath.isEmpty()) return; path = newPath; QSvgGenerator generator; // Создаём объект генератора файла generator.setFileName(path); // Устанавливаем путь к файлу, куда будет сохраняться векторная графика generator.setSize(QSize(scene->width(), scene->height())); // Устанавливаем размеры рабочей области документа в миллиметрах generator.setViewBox(QRect(0, 0, scene->width(), scene->height())); // Устанавливаем рабочую область в координатах generator.setTitle(trUtf8("SVG Example")); // Титульное название документа generator.setDescription(trUtf8("File created by SVG Example")); // Описание документа // С помощью класса QPainter QPainter painter; painter.begin(&generator); // Устанавливаем устройство/объект в котором будем производить отрисовку scene->render(&painter); // Отрисовываем содержимое сцены с помощью painter в целевое устройство/объект painter.end(); // Заканчиваем отрисовку // По окончанию отрисовки получим векторный файл с содержимым графической сцены }
Підсумок
В результаті виконання програмного коду ви отримаєте SVG файл, який успішно відкриється в CorelDraw.
Добрый вечер. Встал вопрос. Каким образом сохранить координаты объектов, потому что в следующем уроке объекты на сцене будут находиться все в одном месте из которого их еще придется перетаскивать
Координаты объектов в данном случае нормально сохраняются. В конце статьи есть урок по восстановлению данных из SVG файла, изучите его. Там показано, как расположить объекты на графической сцене во время восстановления данных.
Здравствуйте!
Как можно добавить текст туда?
Хочу попробовать нарисовать граф и обозначить вершины с дугами.
Добрый день.
Текст можно добавить на графическубюю сцену с помощью QGraphicsTextItem.
Добрый день!
А не подскажете как можно сохранить фон, если это моя собственная картинка? При сохранении просто однотонного фона, не картинки все работает хорошо.
Добрый день.
Не подскажу. Могу только направить. Для это нужно в каком-нибудь популярном svg редакторе смотреть, как будет сохраняться ихображение, и потом попытаться повторить тоже самое средствами Qt.
Вполне возможно, что изображение там или отдельно будет сохраняться или будет как-то встраиваться в SVG файл.