本文主要在于总结文件读写的细节,借助于树结构来呈现出文件读写的用法和用途,当然可以用QSetting 来实现,也比较简单,但是没有下面的方法通用~重在积累!
windows下的txt文本,包括ini文件,都不能通过Tab键输入“\t”,在ubuntu下的gedit可以通过tab键输入制表符"\t"
如下文本(default.txt):
节点1 ***( 名称) ****(数据)
12343 温度 12.3
2345 湿度 1212
//文件读:
#include<QtGui>
MyWidget::MyWidget()
{
QFile file("default.txt");
file.open(QIODevice::ReadOnly);
//dataFromFile=new QString;
dataFromFile=file.readAll();
file.close();
QList<QVariant> rootData;
rootData<<"节点"<<"类型"<<"数据";
//qDebug()<<rootData;
rootItem = new TreeItem(rootData);
setupModelData(dataFromFile.split(QString("\n")),rootItem); QTreeWidget myTreeWidget=new QTreeWidget; ....显示部分不在累述,根据需要可以简单实现}
void MyWidget::setupModelData(constQStringList&lines,TreeItem*parent)
{
QList<TreeItem*> parents;
QList<int> indentations;
parents<<parent;
indentations<<0;int number = 0 ;
while(number<lines.count()){
int position=0;
while(position<lines[number].length()){//分级目录是通过空格来确定的,这里设置每一级在上一级的基础上空4个空格,这里做的是去空格 " "
if(lines[number].mid(position,1)!=" ")
break;
position++;
}
QString lineData=lines[number].mid(position).trimmed();
if(!lineData.isEmpty()){
QStringList columnStrings=lineData.split("\t",QString::SkipEmptyParts);//去掉字符为空的部分
QList<QVariant> columnData;
for(int column=0;column<columnStrings.count();++column)//
columnData<<columnStrings[column];
if(position>indentations.last()){//这里要好好理解下
if(parents.last()->childCount()>0){
parents<<parents.last()->child(parents.last()->childCount()-1);
indentations<<position;
}
}
else{
while(position<indentations.last()&&parents.count()>0){
parents.pop_back();
indentations.pop_back();
}
}//else
parents.last()->appendChild(new TreeItem(columnData,parents.last()));//添加结点
}
number++;
} }
//文件写,读写很相似,但写更要注意细节
void MyWidget::writeTree()
{
QFile file("default.txt");
if(!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
qDebug()<<"Can't open the file!"<<endl;
}
file.resize(0);
QTextStream stream(&file);
int count=rootItem->childCount();
parentItem=rootItem;
qDebug()<<"write ....";
for (int i=0;i<count;i++)
{
QList<QVariant> list=parentItem->child(i)->dataAll();
for (int k = 0; k < 3/*list.size()*/; ++k) {
QVariant dataItem=list.at(k);
qDebug()<<list.at(k);
stream<< dataItem.toString()<<"\t";
}
QVariant dataItem=parentItem->data(0);
stream<<dataItem.toString()<<"\t";
list.clear();
/*QListIterator<QVariant > k(list);
k.toFront();
while (k.hasNext())
{ QVariant dataItem=k.next();
qDebug()<<k.next();
stream<< dataItem.toString();
}
while ( !list2.isEmpty() )
delete list2.takeFirst();
*/
qDebug()<<"for i...";
stream<<"\n";
for(int j=0;j<parentItem->child(i)->childCount();j++)
{
stream<<QString(" ");
QList<QVariant> list2=parentItem->child(i)->child(j)->dataAll();
for (int m = 0; m < 4/*list2.size()*/; ++m) {
QVariant dataItem=list2.at(m);
qDebug()<<list2.at(m);
stream<< dataItem.toString()<<"\t";
}
QVariant dataItem=parentItem->child(i)->data(0);
stream<<dataItem.toString()<<"\t";
list2.clear();
stream<<"\n";
//qDebug()<<"\n";
}
}
//stream.seek(readPos);
//stream <<line_in;
file.flush();
file.close(); }
TreeItem.h
#ifndef TREEITEM_H
#define TREEITEM_H
#include<QList>
#include<QVariant>
class TreeItem
{
public:
TreeItem(const QList<QVariant> &data,TreeItem *parent=0);
~TreeItem();
void appendChild(TreeItem *child);
void removeChild(int position);
TreeItem *child(int row);
int childCount() const;
int columnCount() const;
QVariant data(int column) const;
int row() const;
TreeItem *parent();
bool m_checked;
bool isChecked();
void setCheckState(bool state);
QList<QVariant> dataAll();
private:
QList<TreeItem*> childItems;
QList<QVariant> itemData;
TreeItem *parentItem;
};
#endifTreeItem.cpp
#include <QStringList>
#include "treeitem.h"TreeItem::TreeItem(const QList<QVariant> &data,TreeItem *parent){
parentItem=parent;itemData=data;QVariant dataItem=itemData.at(1);if(!dataItem.isNull())m_checked=dataItem.toBool();elsem_checked=true;}
TreeItem::~TreeItem(){
qDeleteAll(childItems);}
void TreeItem::appendChild(TreeItem *item){
childItems.append(item);}
void TreeItem::removeChild(int position){
/*int k=0;for (; k < childItems.size(); ++k)if(childItems.at(k)==item)break;if(k<childItems.size())*/childItems.removeAt(position);}
TreeItem *TreeItem::child(int row){
return childItems.value(row);}
int TreeItem::childCount() const{
return childItems.count();}
int TreeItem::columnCount() const{
return itemData.count();}
QList<QVariant> TreeItem::dataAll(){
return itemData;}
QVariant TreeItem::data(int column)const{
return itemData.value(column);}
TreeItem *TreeItem::parent(){
return parentItem;}
int TreeItem::row() const{
if(parentItem)return parentItem->childItems.indexOf(const_cast<TreeItem*>(this));return 0;}
bool TreeItem::isChecked(){
return m_checked;}
void TreeItem::setCheckState(bool state){
m_checked=state;QVariant dataItem=itemData.at(1);QVariant check=QVariant(state);if(dataItem.isNull())// itemData[1]=check;//elsem_checked=true;}