基于EasyX写的一个小应用,源码拿走不谢

前言

上一篇分享了分享一个有趣的库,让你学习C语言不会觉得那么枯燥 。本次分享一个基于小应用。


天气预报小程序

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

基于EasyX写的一个小应用,源码拿走不谢


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

基于EasyX写的一个小应用,源码拿走不谢


1、工程

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

基于EasyX写的一个小应用,源码拿走不谢


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

基于EasyX写的一个小应用,源码拿走不谢


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!
");
        exit(1);
    }

    /* 连接服务端 */
    if (-1 == (connect_status = connect(ClientSock, (SOCKADDR*)&ServerSockAddr, sizeof(SOCKADDR))))
    {
        printf("connect error!
");
        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
", 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);
}

代码下载

该代码工程可在私信留言:基于Easy X的天气预报小程序,我看到的话会发给你。

猜你喜欢:

空间换时间,查表法的经典例子

分享一种简单、实用的测量程序运行时间的方法

嵌入式中自定义协议的一些典型例子

如何同时输出调试信息到终端与文件?


1024G 嵌入式资源大放送!包括但不限于C/C++、单片机、Linux等。私信回复1024,即可免费获取!

展开阅读全文

页面更新:2024-04-22

标签:服务端   嵌入式   图标   源码   大杂烩   今天天气   后天   公众   天气   明天   日期   文字   代码   时间   数据   工程   科技

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top