日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

DIY一个高大上带提醒的计时器,简单实用,你还在等什么

發布時間:2024/4/14 编程问答 62 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DIY一个高大上带提醒的计时器,简单实用,你还在等什么 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
小編心語:鏘鏘鏘!小編我又來了!昨天發了一篇比較實用的《Python聊天室》,鑒于反響還不錯,SO ,小編也想給大家多分享點有用的干貨,讓大家邊學邊用。好了,閑話不多說,今天要給各位看官們介紹的是基于C語言的帶提醒功能計時器。
你還在為錯過重要的事情而心煩不已嗎?
你還在為沒搶到某米手機而扼腕嘆息嗎?
你還在為沒領到美食免單而空遺口水嗎?
從今天起,這些都不是問題,且看小編我給你一一道來!

咳咳咳~上菜啦~

dialog+ncurse實現命令行帶提醒功能計時器

我們將那個結合shell編程與C語言編程使用dialog工具與ncurses庫實現一個仿tmux時間風格的帶提醒功能的計時器

一、說明

這次項目課要實現的東西功能很簡單,但是卻用到了好幾個東西,包括dialog,ncurses庫,zenity,moc, 用了這么多東西最后也就是個定時器-_-||。不過我想先告訴你的是為什么是它。這原因呢有兩個,一個是之前看到有用戶反應希望項目課有一些綜合性稍強的內容,這個項目課就是了,結合了shell編程和C語言編程,C語言編程除了包含本身的內容還涉及到了如何使用外部庫來實現我們想要的功能;這第二個原因 是,我自己需要一個這樣的定時器啊,我要每周二中午12點的時候準時搶小米手機(搶了幾次沒搶到啊,就是因為時間沒掐準,不夠快),所以就想要一個定時器 了,我想的是除了要實現基本功能外還要求“看起來,高大上”。

二、功能介紹

既然我是要實現一個命令行的定時器,要想“高大上”,那就必須要用到命令行的圖形庫了,一開始想到的是ncurses,這就得完全用C語言來開發了,后來又想到可以用shell下的dialog(基于ncurses實現的命令行圖形對話框,包含一些常用的構件)來完成一部分功能,比如設定時間的界面可以用dialog的timebox構件來實現,如下圖

本想是不是可以用dislog實現全部我想要的效果,比如在設定時間之后,進入倒計時界面,類似下面的效果


這實際是tmux內建時鐘效果。然后翻翻dialog的文檔,發現連字體大小都沒法設置,也無法設置構件內文本的顯示位置,那就沒辦法了,不過 dislog底層就是基于ncurses來實現的,我也就用ncurses來實現倒計時顯示的這個功能吧。最后實現的效果如下,是不是山寨得跟原版(tmux, ctrl+b t)一樣。


這樣就滿足了嘛,當然不,我們還要再加點東西,讓它像鬧鐘一樣時間到放歌音樂如何,或者再彈個窗,免得我埋頭工作忘了"正事"(搶手機),播放音樂我用moc(一個流行的命令行音樂播放器),彈窗用zentiy(基于gtk構件的簡單彈出式對話框)


?功能介紹完了,下面就讓我們來實現吧

三、具體實現

1.使用dialog設定時間

這個功能在shell腳本中實現

我們創建了一個函數

function SetTime(){local c_hour=`date +%H`local c_minute=`date +%M`local c_time=`date +%H:%M:%S`s_time=`dialog --stdout --title "Set Time" --time-format %H\:%M\:%S --timebox\"Current time is\n$c_time\nPlease set the deadtime\n" 0 0 $c_hour $c_minute 00`}

上面代碼中再SetTime函數內部定義了三個局部變量,用于通過date命令分別獲取系統當前時間的時、分,并完整時間顯示為構件的信息, 這里dialog的第一參數--stdout指定繪制窗口的設備,--title 指定構件的標題,--time-format %H\:%M\:%S,用于指定設置完成后dialog返回的時間格式,--timebox就指定了當前dialog構件的類型(因為dialog支持多種構件類型,所以這里必須指定)。最后5個參數0 0 $c_hour $c_minute 00,分別以空格區分開,表示構件的寬度,高度,小時,分鐘,秒,具體請參看dialog的man文檔。完成后你可以按鍵盤的Tab鍵切換選中項,然后移到你要修改的時間上,使用鍵盤的上下鍵更改數值。

我們首先用shell實現的功能就這些,暫時把它放下,我們再來實現用C語言實現的功能。

2.使用ncurses庫實現倒計時顯示

關于ncurses庫的使用,如果你完成過實驗樓上面的另一個項目課C語言貪吃蛇,那么你應該比較熟悉它的使用了,因為這個項目課不是專門介紹ncuses的,所以這里也不會用更多其它關于ncurses的內容了,當然除了我們用到的。

實現顯示大號字體(數字)如前面的效果圖,因為ncurese本身是沒有關于字體設置的實現的,所以這需要我們自己來繪制,我們考慮可以為每個數字建立一個基于父窗體口的子窗口,然后在每個窗口中繪制一個數字,要繪制數字,我們還需要自定義一組字模(只包含10個數字和一個冒號)。這里我們一共需要 8個子窗體,下面這個函數講創建多個子窗體

void create_clock_subwindow(WINDOW *win){int top_win_width, top_win_height;int starty, startx;int i;// 獲取父窗口的高度好寬度getmaxyx(win, top_win_height, top_win_width);if (top_win_height < D_HEIGHT || top_win_width < D_WIDTH){printf("window is too small, please relize the window\n");return;}// 用于指示創建的子窗體繪制的起始位置starty = (top_win_height - D_HEIGHT) / 2;startx = (top_win_width - D_WIDTH*8-7) / 2;for(i = 0; i < 8; i++){digit_win[i] = subwin(win, D_HEIGHT, D_WIDTH, starty, startx+i*(D_WIDTH+1));}}

八個子窗體都是基于主窗體的相對位置創建的,以便適應你重新更改終端的大小,這其中digit_win是預先聲明的一個全局數組,D_HEIGHT,D_WIDTH,為預先定義的兩個指示每個數字的寬和高的宏定義

WINDOW *digit_win[8];

相信你更關心的是如何定義一個字模,呵呵,自己在紙上畫好一個5*5的格子,然后畫上數字,像你小時候看過的電子表上的數字那樣畫(點陣字體),然后被覆蓋的格子的位置填上1,否則為0,然后基于這11個格子建立一個三維數組就像下面這樣:

char digit[11][5][5] = {{ { 1,1,1,1,1 }, /* 0 */{ 1,0,0,0,1 },{ 1,0,0,0,1 },{ 1,0,0,0,1 },{ 1,1,1,1,1 } },{ { 0,0,0,0,1 }, /* 1 */{ 0,0,0,0,1 },{ 0,0,0,0,1 },{ 0,0,0,0,1 },{ 0,0,0,0,1 } },{ { 1,1,1,1,1 }, /* 2 */{ 0,0,0,0,1 },{ 1,1,1,1,1 },{ 1,0,0,0,0 },{ 1,1,1,1,1 } },{ { 1,1,1,1,1 }, /* 3 */{ 0,0,0,0,1 },{ 1,1,1,1,1 },{ 0,0,0,0,1 },{ 1,1,1,1,1 } },{ { 1,0,0,0,1 }, /* 4 */{ 1,0,0,0,1 },{ 1,1,1,1,1 },{ 0,0,0,0,1 },{ 0,0,0,0,1 } },{ { 1,1,1,1,1 }, /* 5 */{ 1,0,0,0,0 },{ 1,1,1,1,1 },{ 0,0,0,0,1 },{ 1,1,1,1,1 } },{ { 1,1,1,1,1 }, /* 6 */{ 1,0,0,0,0 },{ 1,1,1,1,1 },{ 1,0,0,0,1 },{ 1,1,1,1,1 } },{ { 1,1,1,1,1 }, /* 7 */{ 0,0,0,0,1 },{ 0,0,0,0,1 },{ 0,0,0,0,1 },{ 0,0,0,0,1 } },{ { 1,1,1,1,1 }, /* 8 */{ 1,0,0,0,1 },{ 1,1,1,1,1 },{ 1,0,0,0,1 },{ 1,1,1,1,1 } },{ { 1,1,1,1,1 }, /* 9 */{ 1,0,0,0,1 },{ 1,1,1,1,1 },{ 0,0,0,0,1 },{ 1,1,1,1,1 } },{ { 0,0,0,0,0 }, /* : */{ 0,0,1,0,0 },{ 0,0,0,0,0 },{ 0,0,1,0,0 },{ 0,0,0,0,0 } }};void display_a_digit(WINDOW *win, char digit[5][5], char isnear){int y, x;int color;color = isnear?COLOR_PAIR(4):COLOR_PAIR(3);werase(win); // erase the window before re-put the numberfor(y = 0; y < 5; y++){for(x = 0; x < 5; x++){if (digit[y][x] == 1){wattron(win, color);mvwprintw(win, y, x, "a");wattroff(win, color);}}}}

這樣我們邊實現了可能最讓你覺得困難的一部分代碼

再看主程序

int main(int argc, char *argv[]){char isnear;int screen_width, screen_height;int i;int hour_tens, hour_units, min_tens, min_units, sec_tens, sec_units;time_t current_time;long left_time, end_seconds;char *str;struct tm *c_time;WINDOW *win1;// 為存放提醒信息的字符串分配內存str = malloc(256*sizeof(char));memset(str, '\0', sizeof(char)*256);// 判斷參數輸入參數個數是否正確if (argc < 2 || argc > 4){printf("Usage: %s [options] <seconds> [info strings]\n", argv[0]);return 0;}if (strcmp(argv[1], "-c")){// 將傳遞進的計時時間字符串(以秒為單位的時間)轉換為lang型 left_time = atol(argv[1]);if(argc == 3)strcpy(str, argv[2]);}else if(!strcmp(argv[1], "-c")){// 將傳遞進的計時時間字符串(以秒為單位的時間)轉換為lanleft_time = atol(argv[2]);if (argc == 4)strcpy(str, argv[3]);}else{printf("Usage: %s [options] <seconds> [info strings]\n", argv[0]);return 0;}// 初始化ncursesinitscr();cbreak();noecho();// 自定義顏色start_color();init_color(COLOR_BLACK, 46, 52, 54);init_color(COLOR_BLUE, 52, 101, 164);init_color(COLOR_WHITE, 128, 128, 128);init_pair(1, COLOR_BLACK, COLOR_BLACK); // use for main wininit_pair(2, COLOR_BLUE, COLOR_BLACK); // use for clock wininit_pair(3, COLOR_BLUE, COLOR_BLUE); // use for clock digitinit_pair(4, COLOR_RED, COLOR_RED); // use for clock digitinit_pair(5, COLOR_WHITE, COLOR_BLACK); // use for clock digit// 創建病初始化住窗口getmaxyx(stdscr, screen_height, screen_width);win1 = newwin(screen_height, screen_width, 0, 0);// 設置窗口背景顏色wbkgd(win1, COLOR_PAIR(1));// 獲取系統時間,并計算出計時終止時間time(¤t_time);end_seconds = current_time + left_time;// 進入主循環,開始計時while (left_time){// 休眠一秒鐘,減少cpu占用時間sleep(1);time(¤t_time);left_time = end_seconds - current_time;// 設置接近計時結束的標志,這里設置的為120s,即分鐘,用于當計時只有兩分鐘時講數字顏色換成紅色isnear = (left_time < 120)?TRUE:FALSE;// 當傳入"-c"參數時,使用正常顯示時間模式if (strcmp(argv[1], "-c")){hour_tens = left_time/3600/10;hour_units = left_time/3600%10;min_tens = left_time/60%60/10;min_units = left_time/60%60%10;sec_tens = left_time%60/10;sec_units = left_time%60%10;}else{ // 使用倒計時顯示模式c_time = localtime(¤t_time);hour_tens = c_time->tm_hour/10;hour_units = c_time->tm_hour%10;min_tens = c_time->tm_min/10;min_units = c_time->tm_min%10;sec_tens = c_time->tm_sec/10;sec_units = c_time->tm_sec%10;}// 更新數值前,清除主窗口顯示werase(win1);// 每次創建新的子窗體,以便適應終端的大小調整create_info_subwindow(win1); // info window// 設置提醒信息顯示的字體屬性wattron(info_win, COLOR_PAIR(5));mvwprintw(info_win, 0, 0, "%s", str);wattron(info_win, COLOR_PAIR(5));// 創建計時數字子窗體create_clock_subwindow(win1);// 分別設置子窗體背景顏色for(i = 0; i < 8; i++){wbkgd(digit_win[i], COLOR_PAIR(2));}// 講相應時間的數字繪制到對應窗口中display_a_digit(digit_win[0], digit[hour_tens], isnear);display_a_digit(digit_win[1], digit[hour_units], isnear);display_a_digit(digit_win[2], digit[10], isnear);display_a_digit(digit_win[3], digit[min_tens], isnear);display_a_digit(digit_win[4], digit[min_units], isnear);display_a_digit(digit_win[5], digit[10], isnear);display_a_digit(digit_win[6], digit[sec_tens], isnear);display_a_digit(digit_win[7], digit[sec_units], isnear);// 放置子窗體在主窗體中touchwin(win1);// 刷新窗體wrefresh(win1);}free(str);// 銷毀所有窗體,回收系統資源destory_all_win(win1);endwin();return 0;

主程序最開始完成一些初始化工作,然后在一個主循環完成了主要的倒計時功能。

使用C語言通過ncurses庫實現倒計時的功能完成了,我們再回到shell中去

3.在shell腳本中調用倒計時程序

小編我來說一句,這段小小的代碼相信難不倒大家,小編也就不在這里多做敘述了,當然,如果有看不懂得地方歡迎登陸實驗樓官方網站http://www.shiyanlou.com/courses/?course_type=project&tag=all

里面有更多詳細的內容~

小編先行告退,各位看官請繼續~

4.計時完成后,播放音樂和彈窗提醒

if [ $? -eq 0 ];thenif [ -n "$music" ];thenmocp -S $musicmocp -pfizenity --info --width=100 --text=$infoif [ $? -eq 0 ];then_exitfifi

注意這段代碼,應緊接著上面那段代碼的后面,因為這里用到了$?,你如果學過shell編程,應該能明白這是為什么,$?表示上一個程序的返回值。我們這里判斷它是否的等于0,表示上面的計時程序是否計時結束,如果結束正常返回0,就表示該開始提醒你了。播放音樂就用到了那個mocp程序,你如果不熟悉它的話,可以先安裝好這個程序,并在命令行單獨運行它來熟悉它的使用,遇到任何困難,最好的解決方法就是使用--help參數和man文檔。

$ sudo apt-get install moc

上面mocp的-S的參數表示以服務的形式運行程序,-p為play,-x為退出服務,當然也會停止播放當前音樂,我們使用單獨的函數完成程序退操作

function _exit(){if [ -n "$music" ];thenmocp -xficlearexit 0}

上面的zenity即為一個基于gtk的彈出式對話框程序,后多種構件樣式可選,我們這里使用的是--info構件

5.程序參數處理

如你預見的一樣,這個程序多種參數,如果處理不好可能出現不必要的麻煩,所以這里單獨說明一下這個程序是如何處理參數傳遞的。這里采用了一個很通用的方法,使用shift命令移位傳遞參數

while [ -n "$1" ];docase "$1" in-c) option="-c" ;;-m) music="$2" ;;-i) info="$2" ;;*) show_erro ;;esacif [ "$1" == "-c" ];thenshiftelseshift 2fidone

從上面你可以看到,對-c參數的處理有點不一樣,因為其他幾個參數都會有一個值對應,而-c參數沒有,所以它的移位操作只移動了一個位置。現在我們可以使用如下的方式傳遞參數

$ ./countdown -i "hello shiyanlou" -m music.mp3$ ./countdown -c -i "hello shiyanlou" -m music.mp3$ ./countdown -i "hello shiyanlou"$ ./countdown

?

至此主要的一些麻煩的問題我們都解決了,你在熟悉了上面的實現過程之后,可以參考以下完成代碼(小編在這里插播一句,下面的是需要在我們實驗樓網站的虛擬平臺下才能實現的,不過看到這里,大家應該對于這個程序有了大致的認識,自己稍作修改就可完成屬于自己的一個帶提醒功能的計時器)

$ git clone https://github.com/shiyanlou/countdown.git

C程序使用下面的命令生成

$ gcc disclock.c -o disclock -lncurses

你可能需要安裝如下程序

$ sudo apt-get install libncurses5-dev moc dialog zenity

感謝各位看官的支持~小編以后盡量會在每個工作日,來與大家分享小編整理的干貨,小編會整理一些自己覺得比較實用的程序分享給大家,當然如果大家有需求也可以私信我,或者也可以登陸實驗樓的課程版塊http://www.shiyanlou.com/courses/?course_type=all,如果這些還滿足不了看官您的需求,可以登錄實驗樓的分享版塊http://forum.shiyanlou.com/forum.php?mod=guide&view=newthread,這里有在實驗樓學習的孩紙們分享的干貨和學習心得,最后小編祝大家在碼農的康莊大道上一帆風順!


總結

以上是生活随笔為你收集整理的DIY一个高大上带提醒的计时器,简单实用,你还在等什么的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产美女主播在线观看 | 亚洲成在人 | 中国精品一区二区 | 老外一级片 | 免费的av网站| 亚洲综合丁香 | 视频区小说区 | 中国zzji女人高潮免费 | 91中文字日产乱幕4区 | 日本资源在线 | 亚洲骚片 | 国产一区二区三区四区五区美女 | 亚洲免费中文字幕 | 国产美女精品在线 | 欧色图| 一级片免费的 | 成人做爰免费视频免费看 | 日本一区二区网站 | 影音先锋中文字幕资源 | 欧美h视频在线观看 | www免费网站在线观看 | 91视频网页| 中文字幕亚洲天堂 | 91传媒理伦片在线观看 | 中文字幕丰满孑伦无码专区 | 日本a一级 | 在线艹 | 日韩不卡一二区 | 又紧又大又爽精品一区二区 | 岛国av中文字幕 | 亚洲a精品 | 超碰97久久| av网在线| sm国产在线调教视频 | 成人a毛片久久免费播放 | 天天视频污 | 亚洲久久久久久 | 亚洲一区二区观看播放 | 国产精品国产三级国产 | 国产69精品久久久久久久 | 亚洲成人基地 | 精品少妇久久久 | 91视频免费视频 | 91成人在线观看高潮 | 久久亚洲区| 激情小说专区 | 亚洲九色 | 巨乳美女在线 | 天天干视频在线观看 | 久久成人国产 | 色网站免费观看 | 亚洲自拍偷拍精品 | 亚洲热av | 午夜视频在线看 | 国产污污视频 | 欧美女人一区二区 | 久久久中文 | 激情五月综合色婷婷一区二区 | 91丨porny丨九色 | 中文久久精品 | 久操新在线| 西欧free性满足hd老熟妇 | 中文字幕第四页 | 亚洲AV无码成人精品区明星换面 | 丰满女人又爽又紧又丰满 | 日韩精品免费在线视频 | 色撸撸在线观看 | 永久免费,视频 | 蜜臀久久99精品久久久久久宅男 | 亚洲午夜精品一区二区 | www.超碰在线观看 | xxxx久久| 日本免费精品视频 | 久久精品麻豆 | 久插网| 欧美毛片基地 | 成人福利一区二区 | 日本泡妞xxxx免费视频软件 | 泰剧19禁啪啪无遮挡 | 国产精品成人网 | 亚洲欧美精品suv | 亚洲av成人精品午夜一区二区 | 韩国av免费在线 | 欧美成人一区二区 | 伊人福利视频 | 欧美色偷偷 | av av在线 | 极品久久久久 | 99热影院 | 国产日韩大片 | 国产婷婷色综合av蜜臀av | 涩涩小网站 | 精品国产乱码久久久久久郑州公司 | 高跟肉丝丝袜呻吟啪啪网站av | 在线观看欧美亚洲 | 色婷五月天| 成人污污视频在线观看 | 国产口爆吞精一区二区 | 波多野结衣黄色片 |