Реклама

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

РуководствоQtCorelDraw, QGraphicsScene, Qt, SVG1686

С помощью библиотеки 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.

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

Видеоурок

Реклама

Комментарии

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

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

Комментарии

Только авторизованные пользователи могут оставлять комментарии.
Пожалуйста, Авторизуйтесь или Зарегистрируйтесь
Последние комментарии
  • EVILEG
  • 13 июля 2017 г. 2:12

Qt/C++ - Урок 023. Перетаскивание QGraphicsItem на QGraphicsScene мышью

Ну например так можете сделать.void MoveItem::mousePressEvent(QGraphicsSceneMouseEvent *event){ if (QApplication::mouseButtons() == Qt::RightButton) { this->deleteLa...

  • Mark
  • 13 июля 2017 г. 1:26

Qt/C++ - Урок 023. Перетаскивание QGraphicsItem на QGraphicsScene мышью

Подскажите пожалуйста как в данном проекте по перетаскиванию организовать удаление объекта со scene методом delete item, допустим при щелчке ПКМ по объекту QGraphicsScene. Мои попытки оказалис...

  • EVILEG
  • 10 июля 2017 г. 21:34

Qt/C++ - Урок 048. QThread - работа с потоками с помощью moveToThread

А что делали? Повторяете урок или как? Пытались просто скачать проект в конце статьи и запустить?

Qt/C++ - Урок 048. QThread - работа с потоками с помощью moveToThread

У меня происходит переполнение счетчика count, появляется ошибка malloc(): memory corruption (fast). Не подскажите, как с этим бороться?

  • EVILEG
  • 9 июля 2017 г. 2:07

GameDev на Qt - Урок 3. Уничтожение противников

Поэтому в пятом уроке есть исходники всего проекта )))). Вообще, все эти материалы были не предыдущей версии сайта, которая на WordPress. Во время переноса мог что-то потерять.

Сейчас обсуждают на форуме

тестирование классов в QT

это вопрос.

Как реализовать отправку e-mail

Возможно что уже и нет необходимости в почтовом клиенте, но в своё время так же столкнулся с данной проблемой в QT. Нашел один интересный проект под названием libqxt, там реализовано дов...

  • Asteri
  • 14 июля 2017 г. 12:23

css

Делюсь, может, пригодится когда-нибудь) QTableView QHeaderView { background-color: #ffffff; } Вот так эта проблема лечится, градиент задать не получается, но хоть...

  • EVILEG
  • 12 июля 2017 г. 19:52

QSqlQuery выполнение sql запросов из файла

Мне думается, что это уже будет дело вкуса и вашего взгляда на проект. Если Вы действительно собираетесь просто скармливать своему софту SQL скрипты, которые должны будут выполняться для...

QML Canvas + Line. Bug?

Вот оно что, значит не баг) Спасибо