qt5--从一个天气预报软件中能学到些啥

Learn from weather forecast!!

       你只要会编程,写一个天气预报软件并不难!

     这次我从一个天气预报小软件中学习qt5;当然只是相关的一部分,这里并不涉及到qt的model/view framework,也不涉及2D graphic program,就是一个简单的widget 编程,虽然项目很小,但是还是从中学习到了不少东西。当然这些都比较基础,适合初学者阅读,欢迎大神指点,相互学习交流。当然这里只是我学习的一个思维过程,具体得参考源代码,而且每个人想法不同都会有不同的实现,所以大家写好都可以相互学习,共同进步。

     在我写这个soft之前,是在qt贴吧里面看到有人写了一个天气预报的软件,然后我没有直接去下载源代码,而是去google了下别人的天气预报是怎么写的,一般都是几年前的帖子了。然后我就自己本着完全学习qt API的心态,开始了这个soft项目。

 

实现原理

     在这里,qt只是一个实现soft的工具,而且要学的就是这个工具,所以先说怎么实现天气预报软件,然后再一步一步说qt。

     需要弄明白的就一件事,怎么获取天气数据,网上一大堆,我这里精简下;

就是给天气服务器发送GET请求,这个属于HTTP协议的范畴,具体可以去研究下,这个能学到不少东西哟。

     这里有一个天气服务器:

     http://www.weather.com.cn/data/sk/101010100.html

     http://www.weather.com.cn/data/cityinfo/101010100.html

     http://m.weather.com.cn/data/101010100.html

     这样,我们只要建立一个QTcpSocket套接字,host为www.weather.com.cn

最下面找出同位置的一样,端口号为80(HTTP服务的标准端口),然后建立好链接之后发送host后面的内容:

GET /data/cityinfo/101010100.html HTTP/1.1\r\n\r\n

     然后接受从服务器传过来的数据,解析,显示,over。那问题来了,怎么知道是哪个城市,上面那条命令里面的一串数字就是城市ID。

     http://blog.csdn.net/hello_haozi/article/details/7564223这个博客里面说的很详细,而且在上传的源代码包里面有处理过的城市列表,只是针对我这个程序的文件。

    根据IP获取ID:这个博客里面提到一个根据IP获取城市ID的,经过试验,只能获取到本地IP,那个城市ID不管在哪里都是显示的北京的ID。

 

调试方法

       调试我就用了两种方法:一个是qDebug() ;另外一个就是在界面设置一个QPlainTextEdit控件,这样能显示完全这些信息;

 

QT类的学习

       1、纲

根据实现原理,首先肯定要有窗口小部件(QtWidgets class),显示文字(QLabel class),选择哪个地方的天气查看(QComboBox class),查看数据用于调试(QPlainTextEdit class),数据处理(QString class,QByteArray class,QFile class),还要中文化吧(QTextCodec class),最重要的要连接到天气服务器(QTcpSocket class,QAbastractSocket class等),这样我们就有了一个大纲,从这些类中学习qt。

 

       2、QWidget

       整个窗口就是一个widget小部件,有几种办法可以对界面进行设计(布局);一个是Qt Designer,qt creator也可以设计,这个文件后缀名为.ui;另外一个是直接写代码布局,通常就是layout;

       在这个widget中,我们通常需要和用户交互,这里就是响应事件;比如选择了某个省之后,我们点击一个按钮就获取服务器的天气预报数据,这是响应用户的鼠标事件;比如我们选定省的下拉列表(procomboBox)后,在市的下拉列表(citycomboBox)里面就显示该省有哪些市,同样,还有县级(coucomboBox),这里又要用到信号和槽了,这个是qt的核心功能;

       然后与widget相关的是区分顶级窗口和子窗口,这个在天气预报软件里面没有用到,就先不说了;

       定制窗口,这个也没做,当然后面在扩展的时候提到;

       这里只是一些简单的介绍了,因为基本上用到的都是他的派生类;  

 

       3、QLabel

       QLabel的默认大小为QSize(54,12),表示长度为54个像素,高度为12个像素,但是当天气为“中到大雨转阵雨”这么长的时候就显示不完全,这时候有两种办法来解决QLabel的显示问题:一个是QLabel::resize(QSize(200,12));另一个是QWidget::setGeometry(int x,int y,200,12),x和y是这个QLabel的坐标,后面是大小;

       QLabel显示图片,这个也有一个大小问题,通过qDebug()也能获取到图片大小,或者事先你就知道图片大小,这个问题就好解决了。

 

       4、QComboBox

       这个实现的是下拉框列表类,基本上看了他的成员函数,用到的就是他的一个信号currentIndexChanged,然后进行相关的处理;

 

       5、QPlainTextEdit

       这个只是用来调试,一个是setPlainText,一个是appendPlainText两个属性;

 

       6、数据处理

       这里就是个比较关键的地方,还是想了一下的。

       首先我想的是,直接给服务器发送中文,返回城市名,或者城市ID也好啊,这样就能直接查询天气预报了,几经查询,未果;

       然后觉得中国天气网的查询太麻烦,去找其他提供web service的网站,哎呀,都是要钱的,不要钱的数据也不全;

       最后,还是选择了现在使用的办法,把城市名  和城市ID放到一个文件中,然后直接在每次启动软件的时候存入一个QMap<QString,QString>这样一个容器中,方便选择的时候直接查询到城市ID,结果发现这是最简单最容易实现的解决办法;然后谷百了一下,就下载到了城市数据,然后稍微修改下,就成了现在使用的元数据了;

       数据处理我思考了两个问题,一个是怎么能让三个QComboBox空间联系起来,意思就是说选择省,那么下一个控件就只显示该省的所有市,同样下一个显示选中市的所有县;这样,第二个问题就是,关联起来用哪个数据结构存储数据,这个显然就用QMap最合适了,主要是利用他的键值对特性,但是究竟怎样关联,比如是QMap<QString,int>,还是QMap<QString,QString>,毕竟城市对应的是ID才能获取到天气数据呀;后来恍然大悟,反正我是要发送QString数据给服务器的,所以直接就用第二种了;所以最后的数据结构就用QMap<QString,QMap<Qstring,QStringList>>,这样就解决了所有的问题了。

       那当我们选中好一个城市之后,怎么找到ID,很简单,就直接从存储ID和城市对应的那个QMap容器里面找就是了,这几乎不叫做问题;

       好了,设计数据结构和界面几乎就这么完了。。接下来的就是实现,去看源代码吧,呵呵;

 

       7、QAbstractSocket,QTcpSocket

       我们怎么连接上服务器呢?熟悉TCP/IP的可能很容易就想到用套接字了,QT里面提供的也是极简单的套接字,QTcpSocket;由于我们这个连接的是HTTP服务器,所以理所当然,我第一个想到的是利用QT的HTTP接口,发现不好用,然后就直接用了套接字,我们连接的域名是www.weather.com.cn,所以直接用QAbstractSocket::connectToHost(www.weather.com.cn,80),HTTP众所周知的端口是80,去看看qt的manual就知道,当连接上的时候发送connected信号,在套接字上有数据的时候发送readready信号,这样我们就能够对数据进行处理了,这个不难;


扩展

1、界面美化,比如做个按钮效果,还有背景图片啊,

2、可以再上门添加很多功能,比如发送天气email,比如设置时钟,比如获取PM2.5等等

3、还可以将这个天气控件写成一个类,到时候在其他的应用中直接添加就OK了,你说方便不


这里是源代码http://download.csdn.net/detail/xin289379297/5643939

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值