⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch34.htm

📁 linux-unix130.linux.and.unix.ebooks130 linux and unix ebookslinuxLearning Linux - Collection of 12 E
💻 HTM
📖 第 1 页 / 共 5 页
字号:


XtRealizeWidget(top);



XtAppMainLoop(app);



return(0);



}







void  bye(Widget w, XtPointer clientdata, XtPointer calldata)



{



exit(0);



}



</FONT></PRE>



<P>Refer to Figure 34.6, shown previously, for the output of this listing with the



<TT>#define DO_RADIO</TT> line commented out. By defining the <TT>DO_RADIO</TT> label,



you can make this into a Radio Button application. That is, only one of the buttons



can be selected at one time. Refer to Figure 34.5, shown previously, for the radio



behavior of these buttons.



<H3 ALIGN="CENTER"><A NAME="Heading27<FONT COLOR="#000077">Convenience Functions</FONT></H3>



<P>Usually the time to set resources for a Widget is at the Widget's creation. This



is done either with the <TT>XtVaCreateManagedWidget</TT> call or with the <TT>XmCreate</TT>YYY



call, where YYY is the name of the Widget you are creating.</P>



<P>This test uses the variable argument call to create and manage Widgets. I do it



simply because it's easier for me to see what resources I am setting and to create



them all in one function call. You might have a personal preference to do it in two



steps. Either way is fine. Keep in mind, though, that if you do use the <TT>XmCreate</TT>YYY



call, you have to set the resource settings in a list of resource sets. Listing 34.4



is an example of creating a Label Widget. This is a function that creates a Label



Widget on a Widget given the string <TT>x</TT>.



<H3 ALIGN="CENTER"><A NAME="Heading28<FONT COLOR="#000077">Listing <A NAME="Heading2934.4.



Sample convenience function for creating a label on a form.</FONT></H3>



<PRE><FONT COLOR="#0066FF">/**



*** This is a sample convenience function to create a label



*** Widget on a parent. The string must be a compound string.



**/



Widget makeLabel( Widget onThis, XmString x)



{



Widget   lbl;



Cardinal n;



Arg   arg[5];







n = 0;



XtSetArg(arg[n], XmNalignment, XmALIGNMENT_BEGIN); n++;



XtSetArg(arg[n], XmNlabelString, x); n++;



lbl = XmCreateLabel(&quot;A Label&quot;, onThis, arg, n);



XtManageChild(lbl);



return(lbl);



}



</FONT></PRE>



<P>Or you could use the variable argument lists in creating this label, as shown



in Listing 34.5.



<H3 ALIGN="CENTER"><A NAME="Heading30<FONT COLOR="#000077">Listing <A NAME="Heading3134.5.



Creating a label.</FONT></H3>



<PRE><FONT COLOR="#0066FF">/**



*** Another way of making a label on a parent.



**/



Widget makeLabel( Widget onThis, XmString x)



{



Widget   lbl;



lbl = XmCreateManagedWidget(&quot;A Label&quot;,



      xmLabelWidgetClass, onThis,



      XmNalignment, XmALIGNMENT_BEGIN,



      XmNlabelString, x,



      NULL);







return(lbl);



}



</FONT></PRE>



<P>In either case, it's your judgment call as to which one to use. The variable list



method of creating is a bit easier to read and maintain. But what about setting values



after a Widget has been created? This would be done via a call to <TT>XtSetValue</TT>



with a list and count of resource settings. For example, to change the alignment



and text of a label, you would use <TT>XtSetValues</TT>:</P>



<PRE><FONT COLOR="#0066FF">n = 0;



XtSetArg(arg[n], XmNalignment, XmALIGNMENT_BEGIN); n++;



XtSetArg(arg[n], XmNlabelString, x); n++;



XtSetValues(lbl,arg,n);



</FONT></PRE>



<P>Similarly, to get the values for a Widget, you would use <TT>XtGetValues</TT>:</P>



<PRE><FONT COLOR="#0066FF">Cardinal n; /* usually an integer or short... use Cardinal to be safe */



int align;



XmString x;



...



n = 0;



XtSetArg(arg[n], XmNalignment, &amp;align); n++;



XtSetArg(arg[n], XmNlabelString, &amp;x); n++;



XtGetValues(lbl,arg,n);



</FONT></PRE>



<P>In the case of other Widgets, let's use the Text Widget. This setting scheme is



hard to read, quite clumsy, and prone to typos. For example, when you get a string



for a Text Widget, should you use <TT>x</TT> or address of <TT>x</TT>?</P>



<P>For this reason, Motif provides convenience functions. For example, in the ToggleButton



Widget class, rather than using the combination of <TT>XtSetValue</TT> and <TT>XtSetArg</TT>



calls to get the state, you would use one call, <TT>XmToggleButtonGetState(Widget



w)</TT>, to get the state. These functions are valuable code savers when writing



complex applications. In fact, you should write similar convenience functions whenever



you can't find one that suits your needs.



<H3 ALIGN="CENTER"><A NAME="Heading32<FONT COLOR="#000077">The List Widget</FONT></H3>



<P>This displays a list of items from which the user selects. The list is created



from a list of compound strings. Users can select either one or many items from this



list. The resources for this Widget include the following: <TT>XmNitemCount</TT>:



Determines the number of items in the list.</P>



<P><TT>XmNitems</TT>: An array of compound strings. Each entry corresponds to an



item in the list. Note that a List Widget makes a copy for all items in its list



when using <TT>XtSetValues</TT>; however, it returns a pointer to its internal structure



when returning values to a <TT>XtGetValues</TT> call. Therefore, do not free this



pointer from <TT>XtGetValues</TT>.</P>



<P><TT>XmNselectedItemCount</TT>: The number of items currently selected.</P>



<P><TT>XmNselectedItems</TT>: The list of selected items.</P>



<P><TT>XmNvisibleItemCount</TT>: The number of items to display at one time.<BR>



<BR>



<TT>XmNselectionPolicy</TT>: Used to set single or multiple selection capability.



If set to <TT>XmSINGLE_SELECT</TT>, the user will be able to only select one item.



Each selection will invoke the <TT>XmNsingleSelectionCallback</TT>. Selecting one



item will deselect a previously selected item. If set to <TT>XmEXTENDED_SELECT</TT>,



the user will be able to select a block of contiguous items in a list. Selecting



a new item or more will deselect another previously selected item and will invoke



the <TT>XmNmultipleSelection</TT> callback. If set to <TT>XmMULTIPLE_SELECT</TT>,



the user will be able to select multiple items in any order. Selecting one item will



not deselect another previously selected item but will invoke the <TT>XmNmultipleSelection</TT>



callback. If set to <TT>XmBROWSE_SELECT</TT>, the user can move the pointer (with



the button pressed) across all the selections, but only one item will be selected.



Unlike the <TT>XmSINGLE_SELECT</TT> setting, the user does not have to press and



release the button on an item to select it. The <TT>XmbrowseSelectionCallback</TT>



will be invoked when the button is finally released on the last item browsed.<BR>



<BR>



It is easier to create the List Widget with a call to <TT>XmCreateScrolledList()</TT>



because this will automatically create a scrolled window for you. However, this method



may prove to be slow when compared to <TT>XtSetValues()</TT> calls. If you feel that



speed is important, consider using <TT>XtSetValues()</TT>. You should create the



list for the first time by using <TT>XtSetValues</TT>.</P>



<P>The following convenience functions will make working with List Widgets easier:



<TT>XmListAddItem(Widget w, XmString x, int pos)</TT></P>



<P>This will add the compound string <TT>x</TT> to the List Widget <TT>w</TT> at



the one relative position <TT>pos</TT>. If <TT>pos</TT> is 0, the item is added to



the back of the list. This function is very slow, so do not use it to create a <TT>newlist</TT>,



because it rearranges the entire list before returning.</P>



<P><TT>XmListAddItems(Widget w, XmString *x, int count, int pos);</TT></P>



<P>This will add the array of compound strings <TT>x</TT> of size <TT>count</TT>



to the List Widget <TT>w</TT> from the position <TT>pos</TT>. If <TT>pos</TT> is



0, the item is added to the back of the list. This function is slow, too, so do not



use it to create a <TT>newlist</TT>.</P>



<P><TT>XmDeleteAllItems(Widget w)</TT></P>



<P>This will delete all the items in a list. It's better to write a convenience function



to do</P>



<P><TT>n = 0; XtSetArg(arg[n], XmNitems, NULL); n++; XtSetArg(arg[n], XmNitemCount,



0); n++; XtSetValues(mylist,arg,n);</TT></P>



<P><TT>XmDeleteItem(Widget w, XmString x)</TT></P>



<P>Deletes the item <TT>x</TT> from the list. This is a slow function.</P>



<P><TT>XmDeleteItems(Widget w, XmString *x, int count)</TT></P>



<P>Deletes all the count items in <TT>x</TT> from the list. This is an even slower



function. You might be better off installing a new list.</P>



<P><TT>XmListSelectItem(Widget w, XmString x, Boolean Notify)</TT></P>



<P>Programmatically selects <TT>x</TT> in the list. If <TT>Notify</TT> is TRUE, the



appropriate callback function is also invoked.</P>



<P><TT>XmListDeselectItem(Widget w, XmString x)</TT></P>



<P>Programmatically deselects <TT>x</TT> in the list.</P>



<P><TT>XmListPos( Widget w, XmString x)</TT><BR>



<BR>



Returns the position of <TT>x</TT> in the list. Returns 0 if not found.<BR>



<BR>



Let's use the List Widget for a sample application. See Listing 34.6.



<H3 ALIGN="CENTER"><A NAME="Heading33<FONT COLOR="#000077">Listing <A NAME="Heading3434.6.



Using List Widgets.</FONT></H3>



<PRE><FONT COLOR="#0066FF">/*



** This is a typical Motif application for using a list Widget



*/







#include &lt;X11/Intrinsic.h&gt;



#include &lt;Xm/Xm.h&gt;



#include &lt;Xm/Form.h&gt;



#include &lt;Xm/PushB.h&gt;







#include &lt;Xm/List.h&gt;    /*** for the list Widget ***/



#include &lt;Xm/ScrolledW.h&gt; /*** for the scrolled window Widget ***/







/*** Some items for the list ***/



#define NUMITEMS 8



char *groceries[NUMITEMS] = {



      &quot;milk&quot;,



      &quot;eggs&quot;,



      &quot;bread&quot;,



      &quot;pasta&quot;,



      &quot;cd-rom&quot;,   /** I don't go out often!**/



      &quot;bananas&quot;,



      &quot;yogurt&quot;,



      &quot;oranges&quot;,



      };



/* For the list Widget, we need compound strings */



XmString xarray[NUMITEMS];







#define USE_SCROLL







void  bye(Widget w, XtPointer clientdata, XtPointer calldata);







int main(int  argc, char **argv)



{



Widget top;



XtAppContext app;



Widget aForm;



Widget aList;



Widget aButton;



Arg   args[15];



int   i;







/**



*** Initialize the toolkit.



**/



top = XtAppInitialize(&amp;app, &quot;KBH&quot;, NULL, 0, (Cardinal *)&amp;argc,



            argv, NULL, args, 0);







/**



*** Create a Form on this top-level Widget. This is a nice Widget



*** to place other Widgets on top of.



**/



aForm = XtVaCreateManagedWidget(&quot;Form1&quot;,



      xmFormWidgetClass, top,



      XmNheight,90,



      XmNwidth,200,



      NULL);







/**



*** Add a button on the form you just created. Note how this Button



*** Widget is connected to the form that it resides on. Only



*** left, right, and bottom edges are attached to the form. The



*** top edge of the button is not connected to the form.



**/



aButton = XtVaCreateManagedWidget(&quot;Push to Exit&quot;,



      xmPushButtonWidgetClass, aForm,



      XmNheight,20,



      XmNleftAttachment,XmATTACH_FORM,



      XmNrightAttachment,XmATTACH_FORM,



      XmNbottomAttachment,XmATTACH_FORM,



      NULL);



/**



*** Now create a list of items for this Widget.



**/



for (i=0; i &lt; NUMITEMS; i++)



      xarray[i] = XmStringCreateLtoR(groceries[i],



                  XmSTRING_DEFAULT_CHARSET);







#ifndef USE_SCROLL



/**



*** Then create the list Widget itself. Note this will not



*** put up a scroll bar for you.



**/



aList = XtVaCreateManagedWidget(&quot;Push to Exit&quot;,



      xmListWidgetClass, aForm,



      XmNitemCount, NUMITEMS,



      XmNitems, xarray,



      XmNvisibleItemCount, 4,



      XmNscrollBarDisplayPolicy, XmAS_NEEDED,



      XmNleftAttachment,XmATTACH_FORM,



      XmNrightAttachment,XmATTACH_FORM,



      XmNtopAttachment,XmATTACH_FORM,



      XmNbottomAttachment,XmATTACH_WIDGET,



      XmNbottomWidget,aButton,



      NULL);







#else



/**



*** Alternatively, use the scrolled window with the following code:



**/



 i = 0;



 XtSetArg(args[i], XmNitemCount, NUMITEMS); i++;



 XtSetArg(args[i], XmNitems, xarray); i++;



 XtSetArg(args[i], XmNvisibleItemCount, 4); i++;



 XtSetArg(args[i], XmNscrollBarDisplayPolicy, XmAS_NEEDED); i++;



 XtSetArg(ar

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -