jinfeng_wang

          G-G-S,D-D-U!

          BlogJava 首頁 新隨筆 聯系 聚合 管理
            400 Posts :: 0 Stories :: 296 Comments :: 0 Trackbacks

          http://www.ibm.com/developerworks/cn/linux/guitoolkit/newt/index.html




          NEWT是在Linux下一個基于文本方式的窗口開發(fā)工具,最初是為Red Hat Linux的安裝程序而設計的。本文將告訴您怎樣一步步使用NEWT為自己的應用程序加上文本方式下的窗口界面。

          NEWT簡介

          考慮到Red Hat Linux有軟盤安裝這一安裝方式,安裝代碼運行于有限的資源環(huán)境中,特別是在有限的文件空間中。NEWT的大小一開始就成為一個重要的問題。為了最小化它所占的空間,NEWT的設計思想有下面幾點:

          1. NEWT由C語言寫成,而不是C++
          2. NEWT所有窗口的生成都是基于堆棧的數據結構,窗口的外觀都是統(tǒng)一的模板,不由程序員修改
          3. 輸入設備只支持終端鍵盤
          NEWT 提供C語言的應用程序接口(API),它不直接進行低級屏幕操作,是在S-Lang 庫上實現的。

           

          組件(Components)

          在NEWT中,每一個可顯示的項目稱為組件。組件主要有兩類:Form組件與非Form組件。非Form組件是除Form以外的所有組件。Form邏輯地組織各個組件成為一個功能集。Form是一個容器組件,讓其他組件都裝在其上,有點類似gtk中的垂直盒(Vbox)和水平盒(Hbox)。當一個應用準備從用戶中獲得輸入,就要run一個Form,這也類似于gtk中的gtk_widget_show()。Form組件可以包含其他任何組件,也包含其他的Form作為子Form。

          每一個組件都是由一個屬于newtComponent數據類型的變量唯一標志,這一變量必須由生成該組件的函數建立,而不能由程序員自己建立。屬于newtComponent數據類型的變量其實只是一個指針。

          NEWT程序的開始與結束

          有三個函數是每個NEWT程序都必須用到的,頭兩個用于初始化系統(tǒng)。

          int newtInit(void);
                      void newtCls(void);

          newtInit()必須是每個NEWT程序第一個調用的函數,用于初始化數據結構和重置終端于raw模式。大多數應用在newtInit()后立即調用newtCls(),newtCls()用于清除屏幕,這個函數不是必須的,但有助于優(yōu)化屏幕。

          當一個NEWT程序準備結束時,就要調用以下函數。
          int newtFinished(void);

          newtFinished()恢復終端在調用newtInit()前的狀態(tài),重置原來的輸入狀態(tài)。若沒調用這函數,終端需重啟才能回到命令行狀態(tài)。

          編譯NEWT程序

          在Linux上用gcc編譯時帶 -lnewt 參數。以下所說的函數都可在/usr/include/newt.h(Red Hat Linux 7.1)中找到。

          標志

          NEWT定義了若干個標志(FLAG),這里僅介紹常用的幾個。

          • NEWT_FLAG_RETURNEXIT?D?D當在組件上按回車時程序退出
          • NEWT_FLAG_HIDDEN?D?D輸入不回顯,大多數應用在輸入密碼的情況
          • NEWT_ENTRY_SCROLL?D?D允許滾動輸入
          • NEWT_FLAG_WRAP?D?D換行時整個單詞換行
          • NEWT_FLAG_BORDER?D?D加邊框
          • NEWT_FLAG_MULTIPLE?D?D允許多選

          若要使用多個標志,可對多個標志進行與操作('|')。

          根窗口(root window)

          終端所顯示的背景,只有不被任何窗口遮蓋的部分稱為根窗口。一般地,應用不需使用到根窗口,而把文字寫到屬于自己的窗口上。所有組件都不應放在根窗口上。根窗口只用于顯示一些輔助信息,例如程序的作者姓名、版本等。NEWT提供兩種在根窗口顯示文字的方式,它們是唯一能越出組件自己當前窗口寫文字的NEWT函數。

          void newtDrawRootText(int left, int top, const char *
                      text);

          該函數用于在根窗口指定位置寫出text字苻串,left和top為字苻串text的開始處,left是屏幕x坐標,top是屏幕y坐標。

          Left和top允許為負數。屏幕坐標原點在顯示器的左上角,x坐標從原點出發(fā)至左向右增大,y坐標從原點出發(fā)至上向下增大。點(10,5)表示以左上角為原點x=10,y=5,而left,top為負,表與為正數方向相對。點(-10,5)表以右上角為原點x=10,因此點(10,5)與點(-10,5)在屏幕左右兩邊相對,同理點(10,5)與點(10,-5)在屏幕上下兩邊相對。

          在文本方式下,通常屏幕的最后一行用于顯示幫助信息,如每個快捷鍵所對應的功能等。這一提示行稱為幫助行(help line)。正如前面所述,NEWT是基于堆棧,壓棧Push操作顯示幫助行,出棧Pop操作刪除幫助行。基于棧的操作后面還回遇到。

          void newtPushHelpLine(const char * text);
                      void newtPopHelpLine(void);

          newtPushHelpLine()用于顯示幫助行,text為所要顯示的字苻串指針,若為NULL則顯示缺省的幫助行。NewtPopHelpLine()則刪除幫助行。

          非正常退出 

          在缺省情況下,NEWT程序不能非正常退出,盡管大多數Unix程序可以通過按Ctrl-z強迫退出,但在NEWT不支持此功能。因NEWT初始化時屏蔽所有終端信號。

          typedef void (*newtSuspendCallback)(void);
                      void newtSetSuspendCallback(newtSuspendCallback cb);

          但可通過調用newtSetSuspendCallback()實現Ctrl-z強迫退出的功能,cb是相應的回調函數,它不帶參數,只做清理工作,如newtFinished()等。早期Red Hat Linux的安裝程序當運行到硬盤分區(qū)時,若你使用Fdisk則屏幕回到命令行狀態(tài)運行Fdisk進行分區(qū),退出Fdisk時又回到當前窗口。要實現這種功能,在回調函數中加入下面兩個函數:
          void newtSuspend(void);
                      void newtResume(void);

          newtSuspend()告訴NEWT程序回到終端初始化前的狀態(tài),做需要做的工作。如需要回到NEWT界面,調用newtResume()恢復。

          窗口

          生成窗口有兩種主要方式:
          int newtCenteredWindow(int width, int height, const char * title);
                      int newtOpenWindow(int left, int top, int width, int height, const char * title);

          由名字可知,newtCenteredWindow()在屏幕中心生成窗口,width為窗口寬度,height為窗口高度,title為窗口標題字串指針,標題文字為紅色。由newtOpenWindow()生成的窗口位置由left,top確定,其余參數同上。

          所有窗口的刪除都是用同一種方式,由于NEWT是基于堆棧來操作,只有在棧頂的窗口才能被刪除,位于棧頂的窗口即當前你能看到的不被任何其他窗口遮蓋的窗口。

          void newtPopWindow(void);

          這函數刪除屏幕最頂層的窗口,并重畫被該窗口遮蓋的部分。

          Form

          正如前述那樣,Form是一個容器組件,同一時間只能生成一個Form,所有組件都必須放在Form上,然后運行它。生成一個Form用以下函數:
          newtComponent newtForm(newtComponent vertBar, const char * help, int flags);

          vertBar是垂直滾動條,help是提示信息,通常這兩個參數都不會用到,用NULL即可,flags就是前述的標志。該函數返回標志所生成的Form的變量。

          把組件放在Form上用以下函數:
          void newtFormAddComponent(newtComponent form, newtComponent co);
                      void newtFormAddComponents(newtComponent form, ...);

          newtFormAddComponent()只放一個組件在Form上,而newtFormAddComponents()則可放多個組件,最后用NULL結束。

          然后就運行它:
          newtComponent newtRunForm(newtComponent form);

          其中Form參數是newtForm()返回的變量。

          刪除一個Form:
          void newtFormDestroy(newtComponent form);

          當一個Form被刪除時,其上的組件一同被刪除,并釋放內存資源。

          按鈕

          幾乎所有的Form都包含最小一個按鈕。按鈕分兩類:完全按鈕(full button)和緊縮按鈕(compact button)。完全按鈕富有立體感,緊縮按鈕則單調些。

          newtComponent newtButton(int left, int top, const char * text);
                      newtComponent newtCompactButton(int left, int top, const char * text);

          newtButton()生成完全按鈕,letf,top指定該按鈕位置,text是指向按鈕文字的指針,該函數返回按鈕的newtComponent變量。NewtCompactButton()生成緊縮按鈕,參數及返回值同上。

          標簽

          標簽是NEWT程序最簡單的組件,用于顯示給定的文本但不允許用戶輸入。

          newtComponent newtLabel(int left, int top, const char * text);
                      void newtLabelSetText(newtComponent co, const char * text);

          newtLabel()生成標簽組件,并返回它的newtComponent變量,參數left,top指定標簽組件位置,text為給定的文本。NewtLabelSetText()用于動態(tài)改變標簽組件的文字,co是要改變的標簽組件,test是要改變的字串指針。

          輸入盒(Entry Box)

          輸入盒可讓用戶輸入字符串到Form中然后由應用接收。

          newtComponent newtEntry(int left, int top, const char * initialValue, int width,char ** resultPtr, int flags);
                      void newtEntrySet(newtComponent co, const char * value, int cursorAtEnd);
                      char * newtEntryGetValue(newtComponent co);

          newtEntry()生成輸入盒組件,其中initialValue為初始化字符串指針,若不需則用NULL,width為寬度,resultPtr為指向當前輸入的字符,flags為標志。Flags設為NEWT_ENTRY_SCROLL,當輸入的字串長度等于輸入盒的寬度時輸入盒將往后滾動,否則不能再輸入;Flags設為NEWT_FLAG_HIDDEN 輸入不回顯,主要應用于輸入密碼方面。NewtEntrySet()用于動態(tài)地改變輸入盒的內容,value為字符串指針,cursorAtEnd實質是一個邏輯變量,由于C語言沒有邏輯類型變量,僅用int代替,若為0則表TRUE,指定光標跟隨,非0光標不跟隨輸入。NewtEntryGetValue()返回輸入的字串。

          檢查盒(Checkbox)

          檢查盒可對其代表的內容通過按空格鍵切換預定的各種狀態(tài)。

          newtComponent newtCheckbox(int left, int top, const char * text, char defValue,const char * seq, char * result);
                      char newtCheckboxGetValue(newtComponent co);

          newtCheckbox()生成一個檢查盒,text標明它所代表的內容,defValue為缺省值也即初始值,seq為切換的順序,result指向當前狀態(tài)。如defValue='@',seq="@*X",則初始時為[@],當按空格鍵==》[*]再按空格鍵==》[X],如此循環(huán)。若result為NULL則需 NewtCheckboxGetValue()獲取當前狀態(tài)。

          單選按鈕(Radio Button)

          單選按鈕的外觀與檢查盒非常相似。不同的是單選按鈕是由若干個組成一個集合,當一個單選按鈕被選中時,其他單選按鈕則被清除。若集合中只有一個單選按鈕,它總會被選中,因而就失去了選擇的意義。

          newtComponent newtRadiobutton(int left, int top, const char * text, int isDefault, newtComponent prevButton);
                      newtComponent newtRadioGetCurrent(newtComponent setMember);

          newtRadiobutton()建立單選按鈕集合,text為代表單選按鈕的字符串指針,isDefault是邏輯開關,為1表邏輯TRUE,初始狀態(tài)為選中;為0表FALSE,初始狀態(tài)為不選中。若當前單選按鈕是集合中的第一個,prevButton為NULL讓newtRadiobutton()自動建立一個集合;若不是第一個,prevButton為前一個由newtRadiobutton()生成的單選按鈕。

          范圍(Scale)

          范圍組件通常用于制作水平進度條。

          newtComponent newtScale(int left, int top, int width, long long fullValue);
                      void newtScaleSet(newtComponent co, unsigned long long amount);

          newtScale()生成水平進度條,width為寬度,fullValue為進度條的最大值。NewtScaleSet()用于設置進度條的值。

          文本盒(Textbox)

          文本盒能讓終端顯示一個文本塊。

          newtComponent newtTextbox(int left, int top, int width, int height, int flags);
                      void newtTextboxSetText(newtComponent co, const char * text);

          newtTextbox()建立一個文本盒,其中flags可設為NEWT_FLAG_WRAP、NEWT_FLAG_SCROLL和它們的與操作。文本盒建立后,由newtTextbox()填充文本。

          滾動條(Scrollbar)

          newtComponent newtVerticalScrollbar(int left, int top, int height,int normalColorset, int thumbColorset);

          newtVerticalScrollbar()生成滾動條,normalColorset為滾動條顏色,thumbColorset為滾動塊顏色。

          列表盒(Listboxe)

          列表和是NEWT中最重要的組件,允許多選或單選

          newtComponent newtListbox(int left, int top, int height, int flags);
                      int newtListboxAppendEntry(newtComponent co, const char * text, const void * data);
                      void * newtListboxGetCurrent(newtComponent co);
                      void newtListboxSetWidth(newtComponent co, int width);
                      void newtListboxSetCurrent(newtComponent co, int num);
                      void newtListboxSetCurrentByKey(newtComponent co, void * key);

          newtListbox()生產列表盒,flags可設為NEWT_FLAG_SCROLL、NEWT_FLAG_RETURNEXIT、NEWT_FLAG_BORDER、 NEWT_FLAG_MULTIPLE和它們的與操作。NewtListboxAppendEntry()用于在當前列表盒最后追加一個列表項,每一個個列表項由key唯一標志,key可為任意類型,只要能和其他列表項區(qū)別開來就可以了。data為key數據。操作列表盒的函數還有:

          void newtListboxSetEntry(newtComponent co, void * key, const char * text);
                      int newtListboxInsertEntry(newtComponent co, const char * text, const void * data, void * key);
                      int newtListboxDeleteEntry(newtComponent co, void * key);
                      void newtListboxClear(newtComponent co);





          回頁首


          例子:

          #include <newt.h>
                      #include <stdio.h>
                      void rootwin_show()
                      {
                      newtCls();
                      /*請觀察left,top為正數,為負數地情形*/
                      newtDrawRootText(0, 0, "左上角");
                      newtDrawRootText(-6, 0, "右上角");
                      newtDrawRootText(0, -3, "左下角");
                      newtDrawRootText(-6, -3, "右下角");
                      /*注意helpline缺省時的內容*/
                      newtPushHelpLine(NULL);
                      newtRefresh();
                      sleep(10);
                      newtPushHelpLine("我的幫助行");
                      newtRefresh();
                      sleep(3);
                      newtPopHelpLine();
                      newtRefresh();
                      sleep(1);
                      }
                      void label_button()
                      {
                      newtComponent form, label, entry, button,cb;
                      char * entryValue;
                      newtCls();
                      newtCenteredWindow(50,10,"輸入與標簽演示");
                      /*left,top是相對于中心窗口而言*/
                      label = newtLabel(10, 1, "請輸入:");
                      entry = newtEntry(19, 1, NULL, 20, &entryValue,
                      NEWT_FLAG_SCROLL);
                      newtEntrySet(entry,"\0",0);
                      button = newtButton(10, 5, "完全按鈕");
                      cb=newtCompactButton(25,5,"緊縮按鈕");
                      form = newtForm(NULL,NULL, 0);
                      newtFormAddComponents(form, label, entry, button,cb, NULL);
                      newtRunForm(form);
                      if(*entryValue!='\0')
                      {
                      newtDrawRootText(0,0,"你輸入了:");
                      newtDrawRootText(12,0,entryValue);
                      }
                      else
                      newtDrawRootText(0,0,"無輸入!");
                      newtRefresh();
                      newtFormDestroy(form);
                      sleep(5);
                      }
                      void check_radio()
                      {
                      newtComponent form, checkbox, rb[3], button,lable1,lable2;
                      char cbValue,cv[2];
                      int i;
                      newtCls();
                      newtOpenWindow(10, 8, 40, 11, "檢查盒與單選盒演示");
                      lable1 = newtLabel(2, 1, "檢查盒:");
                      checkbox = newtCheckbox(10, 1, "A checkbox", ' ', " *X", &cbValue);
                      lable2 = newtLabel(2, 4, "單選盒:");
                      rb[0] = newtRadiobutton(10, 3, "Choice 1", 1, NULL);
                      rb[1] = newtRadiobutton(10, 4, "Choice 2", 0, rb[0]);
                      rb[2] = newtRadiobutton(10, 5, "Choice 3", 0, rb[1]);
                      button = newtButton(15, 7, "退出");
                      form = newtForm(NULL, NULL, 0);
                      newtFormAddComponent(form, checkbox);
                      newtFormAddComponent(form, lable1);
                      newtFormAddComponent(form, lable2);
                      for (i = 0; i < 3; i++)
                      newtFormAddComponent(form, rb[i]);
                      newtFormAddComponent(form, button);
                      newtPushHelpLine("<空格健>選擇");
                      newtRefresh();
                      newtRunForm(form);
                      for (i = 0; i < 3; i++)
                      if (newtRadioGetCurrent(rb[0]) == rb[i])
                      {       newtDrawRootText(0, 0, "單選盒:");
                      newtDrawRootText(9, 0, "第");
                      if(i==0)newtDrawRootText(11, 0,"1");
                      if(i==1)newtDrawRootText(11, 0,"2");
                      if(i==2)newtDrawRootText(11, 0,"3");
                      newtDrawRootText(12, 0, "個");
                      }
                      newtDrawRootText(0, 3, "檢查盒狀態(tài):");
                      cv[0]=cbValue;cv[1]='\0';
                      newtDrawRootText(13, 3, cv);
                      newtRefresh();
                      newtFormDestroy(form);
                      sleep(5);
                      }
                      void test()
                      {
                      char message[] = "This is a pretty long message. It will be displayed "
                      "in a newt textbox, and illustrates how to construct "
                      "a textbox from arbitrary text which may not have "
                      "very good line breaks.\n\n"
                      "Notice how literal \\n characters are respected, and "
                      "may be used to force line breaks and blank lines.";
                      newtComponent form, text, button;
                      newtCls();
                      text = newtTextboxReflowed(1, 1, message, 30, 5, 5, 0);
                      button = newtButton(12, newtTextboxGetNumLines(text) + 2, "退出");
                      newtOpenWindow(10, 5, 37,
                      newtTextboxGetNumLines(text) + 7, "文本盒");
                      form = newtForm(NULL, NULL, 0);
                      newtFormAddComponents(form, text, button, NULL);
                      newtRunForm(form);
                      newtFormDestroy(form);
                      }
                      main()
                      {
                      newtComponent ls,fm;
                      int p = 1, q = 2, r = 3, s = 4, t = 5, *u;
                      newtInit();
                      do {
                      newtCls();
                      newtRefresh();
                      newtDrawRootText(0,0,"這是我的一個NEWT演示程序");
                      newtCenteredWindow(50,10,"請選擇");
                      ls = newtListbox(18,3,5,NEWT_FLAG_RETURNEXIT);
                      newtListboxAppendEntry(ls,"根窗口演示",&p);
                      newtListboxAppendEntry(ls,"輸入盒與按鈕",&q);
                      newtListboxAppendEntry(ls,"檢查盒與單選盒",&r);
                      newtListboxAppendEntry(ls,"文本盒",&s);
                      newtListboxAppendEntry(ls,"退出 ",&t);
                      newtPushHelpLine("                Move using the arrow keys and press ENTER to select");
                      fm = newtForm(NULL,NULL,0);
                      newtFormAddComponents(fm,ls,NULL);
                      newtRunForm(fm);
                      u = newtListboxGetCurrent(ls);
                      newtPopWindow();
                      newtFormDestroy(fm);
                      switch(*u) {
                      case 1:
                      rootwin_show();
                      break;
                      case 2:
                      label_button();
                      break;
                      case 3:
                      check_radio();
                      break;
                      case 4:
                      test();
                      break;
                      case 5:
                      newtFinished();
                      exit(0);
                      }
                      } while(1);
                      }
                      

          運行結果如下圖:



           
          posted on 2007-07-20 14:02 jinfeng_wang 閱讀(622) 評論(0)  編輯  收藏 所屬分類: ZZLinux
          主站蜘蛛池模板: 洛浦县| 盐城市| 邵阳市| 桓台县| 莒南县| 内江市| 文水县| 新民市| 通化市| 翁牛特旗| 容城县| 山丹县| 巩留县| 志丹县| 石狮市| 扎兰屯市| 托克逊县| 高州市| 二手房| 息烽县| 彩票| 宜章县| 灌云县| 屏南县| 清涧县| 普兰店市| 绍兴县| 申扎县| 开远市| 兴隆县| 唐山市| 临安市| 光泽县| 盐源县| 乌拉特前旗| 五家渠市| 达日县| 龙里县| 祁东县| 库伦旗| 滦南县|