用QT制作一个抽奖器的总结

时间:2024-03-09 08:30:24

配置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值的使用,构造函数的恰当利用。。。收获颇多,对编程有了更直观的感受,也有了更大的信心。