- 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 файл.