专栏首页编程学习基地基于EasyX的天气预报小程序

基于EasyX的天气预报小程序

前言

上一篇分享了:分享一个有趣的库,让你学习C语言不会觉得那么枯燥。有几位小伙伴发表了自己的看法让我陷入思考。

  • 这个是C++,和C不要搞混淆了,两种语言。
  • 这种没意思,浪费时间。

这里简单说一下。

1、上一篇文章里,我也很明确地在文章里说EasyX是一个C++图形库呀,没说EasyX是C语言图形库。标题与C语言相关是因为初学C的确是可以用这个库来进行学习,可以在CPP文件里写C的语法做一些小程序,本篇笔记我分享的这个小程序的工程虽然是C++工程,但是我完全使用C的语法来实现。

所以这个就不用纠结了,觉得有用则拿走,没用就忽略就好。另外再说一点,初学C的朋友,去写那些课本课后小编程题,还不如学写一些小程序效果来的好一些。

2、你觉得没意思的东西可能别人觉得有意思。Easy X依赖了很多Windows平台的东西,我最近工作中用到了一个模拟器,而这个模拟器的源码恰好与这个有点相关,很巧~

我下一步还在想着看看能不能用Easy X也写一个模拟器出来。知识,只有相互碰撞,才能产生更多的想法~

废话不多说,下面进入本篇笔记正题。

天气预报小程序

这个小程序其实之前已经有分享过了:【socket应用】基于C语言的天气客户端的实现。但是之前做的比较粗糙,之前的效果是这样的:

这次我们借助Easy X来对界面进行一个简单的优化:

1、工程

工程是基于VS2019地C++工程:

基于VS编写代码可能会遇到很多问题,高版本地VS比较排斥一些不安全地函数,比如使用一些socket相关的接口、还有字符串操作相关如sprintf等函数可能会编译不通过,如果编译不通过,按照提示去解决即可,如:

2、主函数

// 微信公众号:嵌入式大杂烩
#include "weather_ui.h"
#include "weather_data_parse.h"

int main(void)
{
 Weather weather_data = {0};
 struct time_data system_tim = {0};
 static u_int cur_sec = 0, last_sec = 0, sec_count = 0;

 /* 获取天气数据 */
 GetWeather((char*)NOW_JSON, (char*)"beijing", &weather_data);   
 GetWeather((char*)DAILY_JSON, (char*)"beijing", &weather_data); 

 /* 创建绘图窗口,分辨率 640x480 */
 initgraph(WINDOW_WIDTH, WINDOW_HEIGHT); 

 /* 设置背景 */
 set_background();

 while (1)
 {
  /* 获取本地时间 */
  system_tim = get_time();

  /* 第一次显示时间及天气 */
  time_data_display(&system_tim);
  weather_display(&weather_data);
  
  /* 1s更新一次时间数据,1小时更新一次天气 */
  cur_sec = system_tim.sec;
  if (cur_sec != last_sec)
  {
   last_sec = cur_sec;
   sec_count++;
   time_data_display(&system_tim);
   if (sec_count > 60 * 60)
   {
    sec_count = 0;
    weather_display(&weather_data);
   }
  }
  Sleep(1000);  
 }
 closegraph();   
 
 return 0;
}

获取天气数据、初始化显示环境、显示时间日期及天气。

3、获取天气数据

// 微信公众号:嵌入式大杂烩
void GetWeather(char* weather_json, char* location, Weather* result)
{
 SOCKET ClientSock;
 WSADATA wd;
 char GetRequestBuf[256] = { 0 };
 char WeatherRecvBuf[2 * 1024] = { 0 };
 char GbkRecvBuf[2 * 1024] = { 0 };
 int  gbk_recv_len = 0;
 int  connect_status = 0;

 /* 初始化操作sock需要的DLL */
 WSAStartup(MAKEWORD(2, 2), &wd);

 /* 设置要访问的服务器的信息 */
 SOCKADDR_IN  ServerSockAddr;
 memset(&ServerSockAddr, 0, sizeof(ServerSockAddr));      // 每个字节都用0填充
 ServerSockAddr.sin_family = PF_INET;        // IPv4
 ServerSockAddr.sin_addr.s_addr = inet_addr(WEATHER_IP_ADDR);  // 心知天气服务器IP
 ServerSockAddr.sin_port = htons(WEATHER_PORT);        // 端口

 /* 创建客户端socket */
 if (-1 == (ClientSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)))
 {
  printf("socket error!\n");
  exit(1);
 }

 /* 连接服务端 */
 if (-1 == (connect_status = connect(ClientSock, (SOCKADDR*)&ServerSockAddr, sizeof(SOCKADDR))))
 {
  printf("connect error!\n");
  exit(1);
 }

 /* 组合GET请求包 */
 sprintf(GetRequestBuf, GET_REQUEST_PACKAGE, weather_json, KEY, location);

 /* 发送数据到服务端 */
 send(ClientSock, GetRequestBuf, strlen(GetRequestBuf), 0);

 /* 接受服务端的返回数据 */
 recv(ClientSock, WeatherRecvBuf, 2 * 1024, 0);

 /* utf-8转为gbk */
 SwitchToGbk((const unsigned char*)WeatherRecvBuf, strlen((const char*)WeatherRecvBuf), (unsigned char*)GbkRecvBuf, &gbk_recv_len);
#if DEBUG
 printf("服务端返回的数据为:%s\n", GbkRecvBuf);
#endif

 /* 解析天气数据并保存到结构体变量weather_data中 */
 if (0 == strcmp(weather_json, NOW_JSON))  // 天气实况
 {
  cJSON_NowWeatherParse(GbkRecvBuf, result);
 }
 else if (0 == strcmp(weather_json, DAILY_JSON)) // 未来三天天气
 {
  cJSON_DailyWeatherParse(GbkRecvBuf, result);
 }

 /* 清空缓冲区 */
 memset(GetRequestBuf, 0, 256);
 memset(WeatherRecvBuf, 0, 2 * 1024);
 memset(GbkRecvBuf, 0, 2 * 1024);

 /* 关闭套接字 */
 closesocket(ClientSock);

 /* 终止使用 DLL */
 WSACleanup();
}

4、解析天气数据

代码太多,略过。文末可获取代码工程。

5、显示数据

// 微信公众号:嵌入式大杂烩
void weather_display(Weather* weather_data)
{
 char tmp_buf[50] = {0};
 IMAGE pDstImg;
 RECT rect;

 /* 设置一些默认样式 */
 setlinecolor(WHITE);
 setbkcolor(BACK_GROUND_COLOR);
 settextstyle(DEFAULT_FONT_HEIGHT, DEFAULT_FONT_WIDTH, DEFAULT_FONT_TYPE);

 /* 分割线 */
 line(0, WINDOW_HEIGHT / 2, WINDOW_WIDTH, WINDOW_HEIGHT / 2);
 line(WINDOW_WIDTH / 3, WINDOW_HEIGHT / 2, WINDOW_WIDTH / 3, WINDOW_HEIGHT);
 line(WINDOW_WIDTH * 2 / 3, WINDOW_HEIGHT / 2, WINDOW_WIDTH * 2 / 3, WINDOW_HEIGHT);

 /* 城市名 */
 settextstyle(CITY_FONT_HEIGHT, CITY_FONT_WIDTH, DEFAULT_FONT_TYPE);
 rect = {CITY_RECT_X0, CITY_RECT_Y0, CITY_RECT_X1, CITY_RECT_Y1};
 memset(tmp_buf, 0, sizeof(tmp_buf));
 sprintf(tmp_buf, "%s", weather_data->name);
 drawtext(tmp_buf, &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

 /* ==========================今天天气实况====================================== */
 /* 今天天气图标 */
 sprintf(tmp_buf, "./img/weather_icon/%s@2x.png", weather_data->code);
 loadimage(&pDstImg, tmp_buf);
 putimage(TODAY_WEATHER_ICON_X, TODAY_WEATHER_ICON_Y, &pDstImg, SRCPAINT);

 /* 今天天气文字 */
 settextstyle(TODAY_TEMPERATURE_FONT_HEIGHT, TODAY_TEMPERATURE_FONT_WIDTH, DEFAULT_FONT_TYPE);
 rect = {TODAT_WEATHER_RECT_X0, TODAT_WEATHER_RECT_Y0, TODAT_WEATHER_RECT_X1, TODAT_WEATHER_RECT_Y1};
 memset(tmp_buf, 0, sizeof(tmp_buf));
 sprintf(tmp_buf, "%s℃ %s", weather_data->temperature, weather_data->text);
 drawtext(tmp_buf, &rect, DT_CENTER | DT_SINGLELINE);

 /* ==========================今天、明天、后天天气=============================== */
 /* 今天日期 */
 settextstyle(DEFAULT_FONT_HEIGHT, DEFAULT_FONT_WIDTH, DEFAULT_FONT_TYPE);
 rect = {BOTTOM_TODAY_DATA_RECT_X0, BOTTOM_TODAY_DATA_RECT_Y0,  BOTTOM_TODAY_DATA_RECT_X1, BOTTOM_TODAY_DATA_RECT_Y1};
 memset(tmp_buf, 0, sizeof(tmp_buf));
 sprintf(tmp_buf, "%s", weather_data->date[0]);
 drawtext(tmp_buf, &rect, DT_CENTER | DT_SINGLELINE);

 /* 今天天气图标 */
 memset(tmp_buf, 0, sizeof(tmp_buf));
 sprintf(tmp_buf, "./img/weather_icon/%s@2x.png", weather_data->code_day[0]);
 loadimage(&pDstImg, tmp_buf);
 putimage(BOTTOM_TODAY_WEATHER_ICON_X, BOTTOM_TODAY_WEATHER_ICON_Y, &pDstImg, SRCPAINT);

 /* 今天气温范围 */
 rect = {BOTTOM_TODAY_TEMP_RANGE_RECT_X0, BOTTOM_TODAY_TEMP_RANGE_RECT_Y0,  BOTTOM_TODAY_TEMP_RANGE_RECT_X1, BOTTOM_TODAY_TEMP_RANGE_RECT_Y1};
 memset(tmp_buf, 0, sizeof(tmp_buf));
 sprintf(tmp_buf, "%s℃~%s℃", weather_data->low[0], weather_data->high[0]);
 drawtext(tmp_buf, &rect, DT_CENTER | DT_SINGLELINE);

 /* 今天天气文字 */
 rect = {BOTTOM_TODAY_WEATHER_RECT_X0, BOTTOM_TODAY_WEATHER_RECT_Y0,  BOTTOM_TODAY_WEATHER_RECT_X1, BOTTOM_TODAY_WEATHER_RECT_Y1};
 memset(tmp_buf, 0, sizeof(tmp_buf));
 sprintf(tmp_buf, "%s", weather_data->text_day[0]);
 drawtext(tmp_buf, &rect, DT_CENTER | DT_SINGLELINE);

 /* 明天日期 */
 settextstyle(DEFAULT_FONT_HEIGHT, DEFAULT_FONT_WIDTH, DEFAULT_FONT_TYPE);
 rect = {BOTTOM_TOMORROW_DATA_RECT_X0, BOTTOM_TOMORROW_DATA_RECT_Y0,  BOTTOM_TOMORROW_DATA_RECT_X1, BOTTOM_TOMORROW_DATA_RECT_Y1};
 memset(tmp_buf, 0, sizeof(tmp_buf));
 sprintf(tmp_buf, "%s", weather_data->date[1]);
 drawtext(tmp_buf, &rect, DT_CENTER | DT_SINGLELINE);

 /* 明天天气图标 */
 memset(tmp_buf, 0, sizeof(tmp_buf));
 sprintf(tmp_buf, "./img/weather_icon/%s@2x.png", weather_data->code_day[1]);
 loadimage(&pDstImg, tmp_buf);
 putimage(BOTTOM_TOMORROW_WEATHER_ICON_X, BOTTOM_TOMORROW_WEATHER_ICON_Y, &pDstImg, SRCPAINT);

 /* 明天气温范围 */
 rect = {BOTTOM_TOMORROW_TEMP_RANGE_RECT_X0, BOTTOM_TOMORROW_TEMP_RANGE_RECT_Y0,  BOTTOM_TOMORROW_TEMP_RANGE_RECT_X1, BOTTOM_TOMORROW_TEMP_RANGE_RECT_Y1};
 memset(tmp_buf, 0, sizeof(tmp_buf));
 sprintf(tmp_buf, "%s℃~%s℃", weather_data->low[1], weather_data->high[1]);
 drawtext(tmp_buf, &rect, DT_CENTER | DT_SINGLELINE);

 /* 明天天气文字 */
 rect = {BOTTOM_TOMORROW_WEATHER_RECT_X0, BOTTOM_TOMORROW_WEATHER_RECT_Y0,  BOTTOM_TOMORROW_WEATHER_RECT_X1, BOTTOM_TOMORROW_WEATHER_RECT_Y1};
 memset(tmp_buf, 0, sizeof(tmp_buf));
 sprintf(tmp_buf, "%s", weather_data->text_day[1]);
 drawtext(tmp_buf, &rect, DT_CENTER | DT_SINGLELINE);

 /* 后天日期 */
 settextstyle(DEFAULT_FONT_HEIGHT, DEFAULT_FONT_WIDTH, DEFAULT_FONT_TYPE);
 rect = {BOTTOM_AFTER_TOMORROW_DATA_RECT_X0, BOTTOM_AFTER_TOMORROW_DATA_RECT_Y0,  BOTTOM_AFTER_TOMORROW_DATA_RECT_X1, BOTTOM_AFTER_TOMORROW_DATA_RECT_Y1};
 memset(tmp_buf, 0, sizeof(tmp_buf));
 sprintf(tmp_buf, "%s", weather_data->date[2]);
 drawtext(tmp_buf, &rect, DT_CENTER | DT_SINGLELINE);

 /* 后天天气图标 */
 memset(tmp_buf, 0, sizeof(tmp_buf));
 sprintf(tmp_buf, "./img/weather_icon/%s@2x.png", weather_data->code_day[2]);
 loadimage(&pDstImg, tmp_buf);
 putimage(BOTTOM_AFTER_TOMORROW_WEATHER_ICON_X, BOTTOM_AFTER_TOMORROW_WEATHER_ICON_Y, &pDstImg, SRCPAINT);

 /* 后天气温范围 */
 rect = {BOTTOM_AFTER_TOMORROW_TEMP_RANGE_RECT_X0, BOTTOM_AFTER_TOMORROW_TEMP_RANGE_RECT_Y0,  BOTTOM_AFTER_TOMORROW_TEMP_RANGE_RECT_X1, BOTTOM_AFTER_TOMORROW_TEMP_RANGE_RECT_Y1};
 memset(tmp_buf, 0, sizeof(tmp_buf));
 sprintf(tmp_buf, "%s℃~%s℃", weather_data->low[2], weather_data->high[2]);
 drawtext(tmp_buf, &rect, DT_CENTER | DT_SINGLELINE);

 /* 后天天气文字 */
 rect = {BOTTOM_AFTER_TOMORROW_WEATHER_RECT_X0, BOTTOM_AFTER_TOMORROW_WEATHER_RECT_Y0,  BOTTOM_AFTER_TOMORROW_WEATHER_RECT_X1, BOTTOM_AFTER_TOMORROW_WEATHER_RECT_Y1};
 memset(tmp_buf, 0, sizeof(tmp_buf));
 sprintf(tmp_buf, "%s", weather_data->text_day[2]);
 drawtext(tmp_buf, &rect, DT_CENTER | DT_SINGLELINE);
}

6、获取系统时间

// 微信公众号:嵌入式大杂烩
struct time_data get_time(void)
{
 time_t t;
 struct tm *tim;
 struct time_data res_time;
 const char *wday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};

 time(&t);  
 tim = localtime(&t); 
 res_time.year = 1900 + tim->tm_year; 
 res_time.mon  = 1 + tim->tm_mon;  
 res_time.mday = tim->tm_mday;   
 res_time.hour = tim->tm_hour;   
 res_time.min  = tim->tm_min;   
 res_time.sec  = tim->tm_sec; 
 strncpy(res_time.week, wday[tim->tm_wday], sizeof(wday[tim->tm_wday]));  

 return res_time;
}

7、显示系统时间

// 微信公众号:嵌入式大杂烩
void time_data_display(struct time_data *tim)
{
 RECT rect;
 char tmp_buf[50] = {0};

 settextstyle(TIME_FONT_HEIGHT, TIME_FONT_WIDTH, DEFAULT_FONT_TYPE);

 /* 年月日、星期 */
 rect = {DATA_RECT_X0, DATA_RECT_Y0, DATA_RECT_X1, DATA_RECT_Y1};
 memset(tmp_buf, 0, sizeof(tmp_buf));
 sprintf(tmp_buf, "%.4d-%.2d-%.2d %s", tim->year, tim->mon, tim->mday, tim->week);
 drawtext(tmp_buf, &rect, DT_CENTER | DT_BOTTOM | DT_SINGLELINE);

 /* 时分秒 */
 rect = {TIME_RECT_X0, TIME_RECT_Y0, TIME_RECT_X1, TIME_RECT_Y1};
 memset(tmp_buf, 0, sizeof(tmp_buf));
 sprintf(tmp_buf, "%.2d:%.2d:%.2d", tim->hour, tim->min, tim->sec);
 drawtext(tmp_buf, &rect, DT_CENTER | DT_SINGLELINE);
}

关键字【天气预报小程序】

·················END·················

本文分享自微信公众号 - 编程学习基地(LearnBase)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-04-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【小程序/工具类】天气预报

    开始项目时,还需要启动另一个项目middleware充当中间件请求weather接口

    用户5997198
  • 微信小程序+和风天气完成天气预报

    花半天时间完成简单的小程序应用。适合小程序初学者。

    极乐君
  • 微信小程序开发的天气预报源码

    开始项目时,还需要启动另一个项目middleware充当中间件请求weather接口

    用户5997198
  • 基于STM32的智能天气预报系统

    这是本人的毕业设计,一个智能的天气预报系统。显示屏上显示各种天气指标及实时显示时间日期等。可以使用触摸屏输入城市名称搜索天气,也可以使用语音搜索天气。

    正念君
  • 程序员装X指南-用基于Python的命令行查天气预报

    作为程序员,能用命令行来完成某些事情的坚决不用GUI,比如用命令行来抢火车票,甚至用命令行终端听音乐,这样在外行看起来有几分神秘感,还能俘获一批小白的芳心,看起...

    sergiojune
  • Android 天气APP(十一)未来七天的天气预报、逐小时预报、UI优化

    如果你看到这里那么你应该看过前面十篇文章了,这是第十一篇,其实写作的原意,并不是我想分这么多章节的,但是不得不分章节,我不能只考虑自己不考虑阅读的人,试问,我这...

    晨曦_LLW
  • C语言七夕必备神器,待那烟花灿烂时,依旧做个单身狗

    缘是美丽的邂逅,爱是心跳的感觉,情是心灵的交会,恋是甜蜜的思念,走在爱与被爱的边缘,你见或者不见,爱你的心始终不改变!C语言诠释爱——为TA写下心中情,生成程序...

    猫咪爱分享
  • python小程序基于Jupyter实现天气查询的方法

    天气查询python小程序第0步:导入工具库第一步:生成查询天气的url链接第二步:访问url链接,解析服务器返回的json数据,变成python的字典数据第三...

    砸漏
  • 微信小程序实例——天气预报开发笔记(进行中...)

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011415782/article/de...

    泥豆芽儿 MT

扫码关注云+社区

领取腾讯云代金券