配置XML文件
加载抽奖信息需要一个合适的配置文件,我知道的除了记事本文件就只有xml文件了。果断选择后者的原因很简单,抽奖信息不是很大,而且可以定向查找和修改。
我一开始是打算完全使用QT自带的函数接口来完成xml文件的配置(包括修改xml文件)的,我首先找到的是QStreamReader及QStreamWriter这两个类,然而看原文档看了半天都只找到生成和解析xml文档而不能修改文档,后面又试了QDomDocument类应该可以修改文档,然而我看了半天试了N多次也没搞定。于是我还是选择去找外部的接口吧,根据老师的推荐很快找到了一段开源代码TinyXML。各种好用,反正最后成功的实现了想要的功能:解析xml,生成xml,修改xml。不过自己做的抽奖器要求也不是很高,TinyXML上还有很多好用的函数没有试。解析xml,生成xml:
1 QFile file("lottor.xml"); 2 3 //判断文件是否存在 4 if (file.exists()) 5 { 6 //加载xml文件 7 TiXmlDocument *xml_doc = new TiXmlDocument(); 8 if (NULL==xml_doc) 9 { 10 return false; 11 } 12 xml_doc->LoadFile("lottor.xml"); 13 TiXmlElement* xml_numberlist = xml_doc->RootElement(); 14 15 //找到对应子元素 16 TiXmlElement* child = xml_numberlist->FirstChildElement("number"); 17 18 //循环加载全部子元素 19 while (child) 20 { 21 const char* number = child->GetText(); 22 ui.listWidgetLottor->addItem(number); 23 24 child = child->NextSiblingElement("number"); 25 } 26 27 } 28 else 29 { 30 TiXmlDocument xml_doc1; 31 32 // 添加XML声明 33 xml_doc1.LinkEndChild(new TiXmlDeclaration( "1.0", "GBK", "" )); 34 35 // 添加根元素 36 TiXmlElement * xml_numberlist = new TiXmlElement("numberlist"); 37 xml_doc1.LinkEndChild(xml_numberlist); 38 39 // 添加number 40 TiXmlElement* xml_child = new TiXmlElement("NUMBER"); 41 xml_numberlist->LinkEndChild(xml_child ); 42 43 // 添加文档内容 44 xml_child->LinkEndChild( new TiXmlText("************")); 45 46 xml_doc1.SaveFile("lottor.xml");
修改xml:
1 QString addNumber=ui.lineEditAdd->text(); 2 string gbkAddNumber=GBK::FromUnicode(addNumber); 3 4 //加载xml文件 5 TiXmlDocument *xml_doc = new TiXmlDocument(); 6 if (NULL==xml_doc) 7 { 8 return false; 9 } 10 xml_doc->LoadFile("lottor.xml"); 11 12 //寻找对应子元素 13 TiXmlElement* xml_numberlist = xml_doc->RootElement(); 14 15 //添加 16 TiXmlElement* xml_child = new TiXmlElement("number"); 17 xml_numberlist->LinkEndChild(xml_child ); 18 xml_child->LinkEndChild( new TiXmlText(gbkAddNumber)); 19 xml_doc->SaveFile("lottor.xml");
关于定时器
一开始觉得定时器没什么用处,以为和windows api上面的Sleep()函数是一个道理。于是最开始,我打算用一个循环和Sleep()函数来实现抽奖列表的滚动。但是我错了,我发现这样并不能实现信息的实时更新,也就是说要等循环完之后才能显示信息,这显然不能实现滚动。这是我才明白定时器的作用,我的理解是,当定义一个timer后,它是从外部以给定的时间间隔来调用功能函数的,这样才能实现信息的实时更新,达到滚动的效果。代码:
1 void dlglott::timerEvent( QTimerEvent * event ) 2 { 3 //TiXmlDocument *xml_doc = new TiXmlDocument(); 4 //if (NULL==xml_doc) 5 //{ 6 // return false; 7 //} 8 //xml_doc->LoadFile("lottor.xml"); 9 //TiXmlElement* xml_numberlist = xml_doc->RootElement(); 10 11 ////找到对应子元素 12 ////TiXmlElement* child = xml_numberlist->FirstChildElement("number"); 13 14 ////循环加载全部子元素 15 //while (1) 16 //{ 17 // TiXmlElement* child = xml_numberlist->FirstChildElement("number"); 18 19 20 const char* number = child->GetText(); 21 ui.labelShow->setText(number); 22 //Sleep(1000); 23 24 lottorResult=(char*)number; 25 26 child = child->NextSiblingElement("number"); 27 if(!child) 28 { 29 child = xml_numberlist->FirstChildElement("number"); 30 } 31 //} 32 33 } 34 35 int dlglott::OnbtnLott() 36 { 37 if(!workingStatu) 38 { 39 timer=startTimer(20); 40 workingStatu=true; 41 } 42 else 43 { 44 killTimer(timer); 45 46 ui.listWidgetResult->addItem(lottorResult); 47 workingStatu=false; 48 } 49 50 51 52 //循环加载全部子元素 53 //while (1) 54 //{ 55 // TiXmlElement* child = xml_numberlist->FirstChildElement("number"); 56 // while (child) 57 // { 58 // const char* number = child->GetText(); 59 // ui.listWidgetResult->addItem("rrr"); 60 // ui.labelShow->setText(number); 61 // Sleep(1000); 62 63 // child = child->NextSiblingElement("number"); 64 // } 65 //} 66 //while (child) 67 //{ 68 // const char* number = child->GetText(); 69 // ui.listWidgetLottor->addItem(number); 70 71 // child = child->NextSiblingElement("number"); 72 //} 73 /*ui.lineEditShow->insert("rrr");*/ 74 //accept(); 75 return 0; 76 }
其他
想来关键的点就这么点,不过还有很多细节,比如bool值的使用,构造函数的恰当利用。。。收获颇多,对编程有了更直观的感受,也有了更大的信心。