Pro komunikaci s programy v JavaScriptu se hodí formát JSON.
http://en.wikipedia.org/wiki/JSON
http://www.json.org/json-cz.html
Přiklad našich dat:
{ "name": "block", "type": "rectangle", "x": 97, "y": 27, "width": 200, "height": 160, "pen": "#ffa500", "brush": "#ffff00", "items": [ { "name": "item1", "brush": "#6495ed", "x": 40, "y": 40, "height": 40 }, { "name": "item2", "brush": "#6495ed", "x": 120, "y": 40 } ] }
Soubor jsonio.cc
http://gitlab.fjfi.cvut.cz/culikzde/sos/-/blob/master/graphics04/jsonio.cc
Qt od verze 5 poskytují třídy pro práci s tímto formátem.
#include <QJsonObject> #include <QJsonArray> #include <QJsonDocument>
Při zápisu grafického prvku si vytvoříme proměnou typu QJsonObject (bez ukazatele).
Objekt se bude v JSONu zapisovat ve složených závorkách.
Tento objekt má předefinované [ ],
jako “index” používáme názvy položek, které se objeví v JSONu před dvojtečkou
a odpovídající hodnoty přiřazujeme do objektu jako do pole.
Pole/seznam se v JSONu zapisuje v hranatých závorkách.
V našem programu ho vytvoříme pomocí QJsonArray a metody append a vložíme do něj vnořené grafické prvky.
QJsonObject writeItem (QGraphicsItem * item) { QJsonObject obj; obj ["type"] = itemType (item); obj ["name"] = item->toolTip (); obj ["x"] = item->x(); obj ["y"] = item->y(); if (QAbstractGraphicsShapeItem * shape = dynamic_cast < QAbstractGraphicsShapeItem * > (item)) { obj ["pen"] = penToString (shape->pen()); obj ["brush"] = brushToString (shape->brush()); if (QGraphicsRectItem * e = dynamic_cast < QGraphicsRectItem * > (shape)) { obj ["width"] = e->rect().width(); obj ["height"] = e->rect().height(); } if (QGraphicsEllipseItem * e = dynamic_cast < QGraphicsEllipseItem * > (shape)) { obj ["width"] = e->rect().width(); obj ["height"] = e->rect().height(); } if (QGraphicsLineItem * e = dynamic_cast < QGraphicsLineItem * > (shape)) { obj ["width"] = e->line().dx(); obj ["height"] = e->line().dy(); } } QJsonArray list; for (QGraphicsItem * t : item->childItems ()) { QJsonObject v = writeItem (t); list.append (v); } obj ["items"] = list; return obj; }
Vytvoříme objekt a do něho vložíme seznam všech samostatných grafických prvků.
Na závěr třída QJsonDocument převede objekt na text vhodný pro uložení do souboru.
QByteArray writeJson (QGraphicsScene * scene) { QJsonObject obj; QJsonArray list; for (QGraphicsItem * item : scene->items (Qt::AscendingOrder)) { if (item->parentItem() == nullptr) list.append (writeItem (item)); } obj ["items"] = list; QJsonDocument doc (obj); QByteArray code = doc.toJson (); return code; }
demo.cc
Ještě upravíme funkci on_actionSave_triggered volanou z menu našeho programu.
Dialogový box nabídne uživateli “filtry” *.json a *.xml.
Funkce saveFile otevře soubor a zapíše do něj data v JSONu nebo XML.
void MainWindow::saveFile (QString fileName, bool json) { QFile f (fileName); if (f.open (QFile::WriteOnly)) { if (json) { QByteArray code = writeJson (scene); f.write (code); } else { QXmlStreamWriter w (&f); writeXml (w, scene); } } else { QMessageBox::warning (NULL, "Save File Error", "Cannot write file: " + fileName); } } const QString dir = QString (); const QString filter = "Json files (*.json);;XML files (*.xml)"; const QString jsonFilter = "Json files"; void MainWindow::on_actionSave_triggered () { QString selectedFilter; QString fileName = QFileDialog::getSaveFileName (this, "Save file", dir, filter, &selectedFilter); if (fileName != "") // saveFile (fileName, selectedFilter.startsWith (jsonFilter)); saveFile (fileName, fileName.endsWith (".json")); }