Qt通过读取XML文件,绘制图形界面

最近需要实现通过读取xml文件的形式动态绘制界面的需求,这样会很方便,在外界修改xml文件就可以了,不需要重新编译程序。

一:XML文件
XML的格式和一些说明,本文就不在介绍了,菜鸟教程有更清晰的入门介绍:菜鸟教程_XML

二:QT中读取XML的类和常用函数
QT中提供了一个读取XML文件的类:QXmlStreamReader
头文件:

#include 

这个类在使用时会创建一个读取xml文件的迭代器

QXmlStreamReader xmlReader(&filename); //xmlReader就是一个迭代器

该类常见的一些接口函数:

readNextStartElement();//挨个读入节点
isStartElement();//判断节点的开始
isEndElement();//判断节点的结束
name();//得到当前节点的名字
readElementText();//访问当前节点的内容
attributes();//获取还有属性节点的属性
atEnd();//判断XML文件是否结束
hasError();//判断XML文件是否出错

三:代码思路
XML文件实际上就是一个树状结构,所以需要一段一段的去读,先设置一个迭代器,找到根节点,然后去寻找根节点下面的内容,然后再对根节点中的内容进行判定,符合条件的执行代码,取出你想取出的数据,如果不需要就直接跳过,读完一个节点的内容接着转到下一个节点去,就是读完左节点再到中间节点,直到将根节点遍历结束,就是读完XML文件。

代码模式:
if(xmlReader.name() == "根节点名字" && xmlReader.isStartElement())
{
   xmlReader.readNextStartElement();
   while(!(xmlReader.name() == "根节点名字" && xmlReader.isEndElement())
   { 
        xmlReader.readNextStartElement();
        if(xmlReader.name() == "节点名字1" && xmlreader.isStartElement()) 
        {  
           while(!(xmlReader.name() == "节点名字1" && xmlReader.isEndElement())
           {      ......     }   
        }  
        else if(xmlReader.name() == "节点名字2" && xmlreader.isStartElement())
        {
           while(!(xmlReader.name() == "节点名字2" && xmlReader.isEndElement())
           {      ......     }    
        }   
   }
} 

四:代码实现
1,准备一个XMl文档:
testconfig.xml


<MSG>
  <Button id ="main_interface">
    <title>
	  <Name>主界面Name>
      <Width>90Width>
      <Height>40Height>
      <Xcoordinate>250Xcoordinate>
      <Ycoordinate>250Ycoordinate>
    title>
  Button> 
MSG>

2,新建一个config文件
config.h

#ifndef CONFIG_H
#define CONFIG_H
#include 
#include 
#include 
#include 
#include 

class config
{
public:
    config();
    //读取XML文件,并存到一个list容器里面
    QStringList readConfig();
};

#endif // CONFIG_H

config.cpp

#include "config.h"

config::config()
{

}

QStringList config::readConfig()
{
       //需要打开的文件
       QFile file;

       //节点的名字
       QString nodename;

       //最终输出的内容
       QStringList OutPut;
       //打开文件路径
       file.setFileName(qApp->applicationDirPath()+"/test_xml/testconfig.xml");
       if (!file.exists())
       {
           qDebug() << "testconfig.xml文件不存在";
       }
       else
       {
           qDebug() << "testconfig.xml文件存在";
       }
       //打开文件
       if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
       {
           qDebug()<<"打开文件失败!";
       }
       else
       {
           //读取xml文件的迭代器
           QXmlStreamReader xmlreader(&file);
           qDebug() << "testconfig.xml文件存在,且打开文件成功!";

           //当文件没有结束且没有出错执行下面的代码
           while(!xmlreader.atEnd() || !xmlreader.hasError())
           {
               //找到非根节点下的第一个子节点
               xmlreader.readNextStartElement();
               //第一个子节点Button
               nodename = xmlreader.name().toString();
               //如果是第一个子节点的开始执行下列代码
               if(nodename == "Button" && xmlreader.isStartElement())
               {
                   //读取出附加信息
                   xmlreader.attributes().value("id").toString();
                   //添加到输出的字符串里
                   OutPut.append(QString("%1").arg(xmlreader.attributes().value("id").toString()));
                   //如果子节点中的内容没有结束
                   while(!(nodename == "Button" && xmlreader.isEndElement()))
                   {
                       //挨个读入节点
                       xmlreader.readNextStartElement();
                       nodename = xmlreader.name().toString();
                       if(nodename == "Name" && xmlreader.isStartElement())
                       {
                           while(!(nodename == "Name" && xmlreader.isEndElement()))
                           {
                               OutPut.append(QString("%1").arg(xmlreader.readElementText()));
                           }
                       }
                       else if(nodename == "Xcoordinate" && xmlreader.isStartElement())
                       {
                           while(!(nodename == "Xcoordinate" && xmlreader.isEndElement()))
                           {
                               OutPut.append(QString("%1").arg(xmlreader.readElementText()));
                           }
                       }
                       else if(nodename == "Ycoordinate" && xmlreader.isStartElement())
                       {
                           while(!(nodename == "Ycoordinate" && xmlreader.isEndElement()))
                           {
                               OutPut.append(QString("%1").arg(xmlreader.readElementText()));
                           }
                       }
                       else if(nodename == "Width" && xmlreader.isStartElement())
                       {
                           while(!(nodename == "Width" && xmlreader.isEndElement()))
                           {
                                OutPut.append(QString("%1").arg(xmlreader.readElementText()));
                           }
                       }
                       else if(nodename == "Height" && xmlreader.isStartElement())
                       {
                           while(!(nodename == "Height" && xmlreader.isEndElement()))
                           {
                                OutPut.append(QString("%1").arg(xmlreader.readElementText()));
                           }
                       }
                   }
               }
           }

           file.close();
           qDebug()<<"文件关闭"<<endl;

           qDebug()<<"xml文件读取完成"<<endl;
           return OutPut;
       }
}

3,在mainwindow里面绘制界面
mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include 
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "config.h"
#include 
#include 
#include 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    config config;
    QStringList str;

    str = config.readConfig();
    for (int i = 0; i<str.count();i++)
    {
        qDebug()<<str.at(i)<<endl;
    }
    QPushButton *aa = new QPushButton(this);
    aa->setText(str.at(1));
    aa->setGeometry(str.at(5).toInt(),str.at(4).toInt(),str.at(2).toInt(),str.at(3).toInt());

}

MainWindow::~MainWindow()
{
    delete ui;
}

main.cpp

#include "mainwindow.h"
#include 

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

五:运行结果
Qt通过读取XML文件,绘制图形界面_第1张图片
六:结语
这个并不是通用的,仅供参考,每个人都要自己写一个适合自己的祖传代码,这样以后复用性很高。

你可能感兴趣的:(XML,xml,qt,开发语言)