可以導出控件佈局和屬性設置數據到xml文件或者其餘文件,也是一個很是實用的功能,相似於QtDesigner中把頁面設計好之後生成的.ui結尾的文件,其實就是xml文件,按照約定的規則存儲好控件名稱和屬性名稱及對應的屬性值,而後打開的時候按照這個規則取出來就好了。每一個控件還有固定的幾個數據須要存儲,好比XY軸和對應的寬度高度,而後在xml數據文件的最開始還能夠存儲整個畫布的寬度高度以便其餘用途。導出到xml格式,是爲了方便解析,畢竟xml數據格式的解析,各類語言平臺都有,並且都是很是成熟快速的。其實還能夠考慮存儲到數據庫,這樣就更增強大了,可以存儲的東西更多,能夠乾的事情更多。node
體驗地址:https://pan.baidu.com/s/1A5Gd77kExm8Co5ckT51vvQ 提取碼:877p 文件:可執行文件.ziplinux
void frmMain::saveFile(const QString &fileName) { QFile file(fileName); if (!file.open(QFile::WriteOnly | QFile::Text | QFile::Truncate)) { return; } //以流的形式輸出文件 QTextStream stream(&file); //構建xml數據 QStringList list; //添加固定頭部數據 list << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; list << QString("<canvas width=\"%1\" height=\"%2\">") .arg(ui->centralwidget->width()).arg(ui->centralwidget->height()); //從容器中找到全部控件,根據控件的類名保存該類的全部屬性 QList<QWidget *> widgets = ui->centralwidget->findChildren<QWidget *>(); foreach (QWidget *w, widgets) { const QMetaObject *metaObject = w->metaObject(); QString className = metaObject->className(); QStringList values; //若是當前控件的父類不是主窗體則無需導出,有些控件有子控件無需導出 if (w->parent() != ui->centralwidget || className == "SelectWidget") { continue; } //metaObject->propertyOffset()表示當前控件的屬性開始索引,0開始的是父類的屬性 int index = metaObject->propertyOffset(); for (int i = index; i < metaObject->propertyCount(); i++) { QMetaProperty p = metaObject->property(i); QString nodeName = p.name(); QVariant nodeValue = p.read(w); //枚舉值要特殊處理,須要以字符串形式寫入,否則存儲到配置文件數據爲int if (p.isEnumType()) { QMetaEnum enumValue = p.enumerator(); nodeValue = enumValue.valueToKey(nodeValue.toInt()); } QString temp = nodeValue.toString().toLocal8Bit().constData(); values << QString("%1=\"%2\"").arg(nodeName).arg(temp); //qDebug() << nodeName << nodeValue; } //逐個添加界面上的控件的屬性 QString str = QString("\t<%1 x=\"%2\" y=\"%3\" width=\"%4\" height=\"%5\" %6/>") .arg(className).arg(w->x()).arg(w->y()).arg(w->width()).arg(w->height()).arg(values.join(" ")); list << str; } //添加固定尾部數據 list << "</canvas>"; //寫入文件 QString data = list.join("\n"); stream << data; file.close(); }