I am using Motif on a Linux platform and have a set of RadioBoxes (mutually exclusive) where one is always selected.
If the user changes the radio box selection (by selecting another toggle button), everything works great.
If the user presses a button on the screen defined to be a "RESET" button, I reset the old settings programmatically and everything appears ok but it isn`t. When the user tries to reselect the toggle button they last selected (which is now unselected since the program reset to another toggle button), the toggle button they try to select looks like it isn`t selected but refuses to become selected. It is as though the toggle button still thinks it is set even though my program changed it.
I looked through the Motif FAQs and see where Kenton Lee recommends setting the XmNmenuHistory resource for the radio box to the button I want to be selected so I have done this. I also use XmToggleButtonSetState(w, True, True) to set the new toggle button to be selected and, as I said, it "appears" to be selected. The old toggle button still thinks *it* is the one selected though and won`t let the user select it.
The only way to select the unselected toggle button is to reselect the one that is selected, then select the unselected one but that is kludgy and I can`t deliver it like that.
Does anyone have any suggestions?
THANKS VERY MUCH!
Julie
‹ Sorry, I redo my request for help.... Cannot create Motif or X11 instance ›
Tue, 08/07/2012 - 15:06
#1
HELP! RadioBoxes not working!
hi julie,
i have this same problem, check out this subject on this forum
problems with toggle button between linux and HP-UX posted by me, i havent recd. any answer from anybody so far.
this works fine on hp-ux but not on linux.
i am working on it, i will come up with a solution very soon.
at the same time , what u can do is click some other toggle button and press the button which u want to select , it will work fine.
did u use XmCreateSimpleRadioBox with XmVaRADIOBUTTON attributes...
another alternative
do this this will work fine. create seperate toggle buttons for a same parent - where parent being a rowcolumn widget and set its radio behaviour as True
XmNradioBehaviour , True
this is a good alternative and will always work across platforms,
as i have code which creates radioboxes both ways, and the first kind results in the strange behaviour in Linux which i have posted already in this forum.
hope i was of enough help , i am in the process of figuring out why that particular problem arises in linux
regards
ragu
i am currently online, if u need more help , please contact me.
It sounds like what you`re doing is reasonable.
To really fix up the situation, you can do this extra work, which shouldn`t be required in your RESET processing, turn off the radio-behavior characteristics of the enclosing XmRowColumn. Then reset the buttons as you want. Then turn the radio-behavior resource back on. (I assume your application can deal with extra callbacks during this time.)
Hi Ragu,
Thank you for your help. I used Builder Xcessory to design my GUI, specifying a RadioBox widget with two toggle button children and the code that is generated calls XmCreateRadioBox()
ac = 0;
XtSetArg(args[ac], XmNnumColumns, 1); ac++;
XtSetArg(args[ac], XmNpacking, XmPACK_TIGHT); ac++;
XtSetArg(args[ac], XmNspacing, 3); ac++;
XtSetArg(args[ac], XmNradioAlwaysOne, True); ac++;
XtSetArg(args[ac], XmNx, 248); ac++;
XtSetArg(args[ac], XmNy, 0); ac++;
XtSetArg(args[ac], XmNwidth, 163); ac++;
XtSetArg(args[ac], XmNheight, 68); ac++;
XtSetArg(args[ac], XmNisHomogeneous, False); ac++;
class_in->unit_radiobuttons = XmCreateRadioBox(
class_in->form11, (char *)"unit_radiobuttons",
args, ac);
So if I had just created a "do-it-yourself" radiobox using a rowcolumn and setting XmNradioBehaviour to True it would not have this problem? That`s interesting. I will remember that for any future radioboxes I create(!)
THANK YOU for your help!!
Julie
Thanks for your idea. I will try it. If I can`t get that to work, I`ll go with Ragu`s suggestion to get rid of my radiobox widget and just create a rowcolumn with radio behavior set to TRUE.
THANK YOU BOTH VERY MUCH FOR YOUR HELP!!
Julie
Ok, I just tried this solution but it apparently won`t work for me because I am not using a rowcolumn widget. I have an XmForm widget which contains an XmRadioBox widget which contains two XmToggleButton widgets. I do not have a rowcolumn widget. I tried turning radioBehavior off on the XmRadioBox widget then setting my toggle buttons (one to TRUE the other to FALSE) then turning radioBehavior back on - but this did not work any differently.
I guess I will need to get rid of my radiobox and just use a rowcolumn with radioBehavior, as suggested by Ragu.
Thank you for trying!
Julie
Hi Ragu,
I changed my RadioBox to a RowColumn and I, unfortunately, seem to have the same problem (!) Maybe there`s something funny in my code?
THE ROW COLUMN WIDGET CREATION
ac = 0;
XtSetArg(args[ac], XmNnumColumns, 1); ac++;
XtSetArg(args[ac], XmNpacking, XmPACK_TIGHT); ac++;
XtSetArg(args[ac], XmNradioBehavior, True); ac++;
XtSetArg(args[ac], XmNspacing, 3); ac++;
XtSetArg(args[ac], XmNisHomogeneous, True); ac++;
XtSetArg(args[ac], XmNradioAlwaysOne, True); ac++;
XtSetArg(args[ac], XmNx, 248); ac++;
XtSetArg(args[ac], XmNy, 0); ac++;
XtSetArg(args[ac], XmNwidth, 163); ac++;
XtSetArg(args[ac], XmNheight, 68); ac++;
class_in->unit_radiobuttons = XmCreateRowColumn(
class_in->form11, (char *)"unit_radiobuttons",
args, ac);
ONE OF THE TOGGLE BUTTONS BEING CREATED
XtSetArg(args[ac], XmNlabelString, tmp0); if (argok) ac++;
XtSetArg(args[ac], XmNset, True); ac++;
XtSetArg(args[ac], XmNindicatorType, XmONE_OF_MANY); ac++;
XtSetArg(args[ac], XmNwidth, 157); ac++;
XtSetArg(args[ac], XmNheight, 34); ac++;
class_in->recordsToggle = XmCreateToggleButton(
class_in->unit_radiobuttons,(char *)"recordsToggle",
args, ac);
OTHER TOGGLE BUTTON BEING CREATED (Generated code...)
XtSetArg(args[ac], XmNlabelString, tmp0); if (argok) ac++;
XtSetArg(args[ac], XmNspacing, 4); ac++;
XtSetArg(args[ac], XmNmarginHeight, 2); ac++;
XtSetArg(args[ac], XmNindicatorType, XmONE_OF_MANY); ac++;
XtSetArg(args[ac], XmNindicatorSize, 13); ac++;
XtSetArg(args[ac], XmNwidth, 157); ac++;
XtSetArg(args[ac], XmNheight, 25); ac++;
class_in->megabytesToggle = XmCreateToggleButton(
class_in->unit_radiobuttons,(char *)"megabytesToggle",
args, ac);
A SNIPPET OF MY RESET ROUTINE WHERE I PROGRAMMATICALLY SET A TOGGLE BUTTON TO TRUE (AND ANOTHER TO FALSE)
XmToggleButtonSetState(p_tapeicon->recordsToggle,
True, True);
XmToggleButtonSetState(p_tapeicon->megabytesToggle,
False, True);
For some reason, the toggle button the user presses last thinks it is still selected even when I force it to False using XmToggleButtonSetState(). I have even done a XmToggleButtonGetState() afterwards and it knows it isn`t on. I have also checked the setting of the XmNmenuHistory resource for the row column to see which widget it thinks is currently set and it also knows the correct toggle button (the one I set).
There must be some other resource that the widget is looking at that I am somehow not setting?
I am totally baffled now since I was sure your suggestion would work.
Do you have any thoughts?
Thank you!
Julie
Hi Ragu,
I changed my RadioBox to a RowColumn and I, unfortunately, seem to have the same problem (!) Maybe there`s something funny in my code?
THE ROW COLUMN WIDGET CREATION
ac = 0;
XtSetArg(args[ac], XmNnumColumns, 1); ac++;
XtSetArg(args[ac], XmNpacking, XmPACK_TIGHT); ac++;
XtSetArg(args[ac], XmNradioBehavior, True); ac++;
XtSetArg(args[ac], XmNspacing, 3); ac++;
XtSetArg(args[ac], XmNisHomogeneous, True); ac++;
XtSetArg(args[ac], XmNradioAlwaysOne, True); ac++;
XtSetArg(args[ac], XmNx, 248); ac++;
XtSetArg(args[ac], XmNy, 0); ac++;
XtSetArg(args[ac], XmNwidth, 163); ac++;
XtSetArg(args[ac], XmNheight, 68); ac++;
class_in->unit_radiobuttons = XmCreateRowColumn(
class_in->form11, (char *)"unit_radiobuttons",
args, ac);
ONE OF THE TOGGLE BUTTONS BEING CREATED
XtSetArg(args[ac], XmNlabelString, tmp0); if (argok) ac++;
XtSetArg(args[ac], XmNset, True); ac++;
XtSetArg(args[ac], XmNindicatorType, XmONE_OF_MANY); ac++;
XtSetArg(args[ac], XmNwidth, 157); ac++;
XtSetArg(args[ac], XmNheight, 34); ac++;
class_in->recordsToggle = XmCreateToggleButton(
class_in->unit_radiobuttons,(char *)"recordsToggle",
args, ac);
OTHER TOGGLE BUTTON BEING CREATED (Generated code...)
XtSetArg(args[ac], XmNlabelString, tmp0); if (argok) ac++;
XtSetArg(args[ac], XmNspacing, 4); ac++;
XtSetArg(args[ac], XmNmarginHeight, 2); ac++;
XtSetArg(args[ac], XmNindicatorType, XmONE_OF_MANY); ac++;
XtSetArg(args[ac], XmNindicatorSize, 13); ac++;
XtSetArg(args[ac], XmNwidth, 157); ac++;
XtSetArg(args[ac], XmNheight, 25); ac++;
class_in->megabytesToggle = XmCreateToggleButton(
class_in->unit_radiobuttons,(char *)"megabytesToggle",
args, ac);
A SNIPPET OF MY RESET ROUTINE WHERE I PROGRAMMATICALLY SET A TOGGLE BUTTON TO TRUE (AND ANOTHER TO FALSE)
XmToggleButtonSetState(p_tapeicon->recordsToggle,
True, True);
XmToggleButtonSetState(p_tapeicon->megabytesToggle,
False, True);
For some reason, the toggle button the user presses last thinks it is still selected even when I force it to False using XmToggleButtonSetState(). I have even done a XmToggleButtonGetState() afterwards and it knows it isn`t on. I have also checked the setting of the XmNmenuHistory resource for the row column to see which widget it thinks is currently set and it also knows the correct toggle button (the one I set).
There must be some other resource that the widget is looking at that I am somehow not setting?
I am totally baffled now since I was sure your suggestion would work.
Do you have any thoughts?
Thank you!
Julie
so what happened any luck...
regards
ragu
No luck. Check out my post from 911am (so I don`t repeat it here).
I am baffled.
why are you calling XmToggleButtonSetState with True(last parameter), this will once again call the Toggle Button valuChanged Callback if you have any and this can result in unwanted result.
change the last parameter to False....
regards
ragu
okay i will give my code snippet ,
Creation of Toggle Buttons
---------------------------
c = 0;
XtSetArg(arg[c], XmNrightAttachment, XmATTACH_POSITION); c++;
XtSetArg(arg[c], XmNrightPosition, Fstnr_ModeRadio_RightPos); c++; //80
XtSetArg(arg[c], XmNtopAttachment, XmATTACH_FORM); c++;
XtSetArg(arg[c], XmNbottomAttachment, XmATTACH_FORM); c++;
XtSetArg(arg[c], XmNleftAttachment, XmATTACH_POSITION); c++;
XtSetArg(arg[c], XmNleftPosition, Fstnr_ModeRadio_LeftPos); c++; //20
XtSetArg(arg[c], XmNorientation, XmHORIZONTAL); c++;
_FstnrModeRadioWgt = XmCreateRadioBox(_FstnrModeForm, "Radio Box", arg, c);
XtManageChild(_FstnrModeRadioWgt);
_FstnrAutoModeRadioWgt = XtVaCreateManagedWidget("Auto",
xmToggleButtonWidgetClass, _FstnrModeRadioWgt,
XmNindicatorSize, Fstnr_Radio_IndicatorSize,
NULL);
MList[FSTNR_AUTO_MODE].Index = FSTNR_AUTO_MODE;
MList[FSTNR_AUTO_MODE].FAList = this;
XtAddCallback(_FstnrAutoModeRadioWgt, XmNvalueChangedCallback, FstnrModeRadioToggledCB, &MList[FSTNR_AUTO_MODE]);
_FstnrManualModeRadioWgt = XtVaCreateManagedWidget("Manual",
xmToggleButtonWidgetClass, _FstnrModeRadioWgt,
XmNindicatorSize, Fstnr_Radio_IndicatorSize,
NULL);
MList[FSTNR_MANUAL_MODE].Index = FSTNR_MANUAL_MODE;
MList[FSTNR_MANUAL_MODE].FAList = this;
XtAddCallback(_FstnrManualModeRadioWgt, XmNvalueChangedCallback, FstnrModeRadioToggledCB, &MList[FSTNR_MANUAL_MODE]);
Forcing XmNset on toggle Buttons - equal to your reset
-------------------------------- ------------------
void SetCurrentModeItemState()
{
XtVaSetValues(_FstnrAutoModeRadioWgt, XmNset, False, NULL);
XtVaSetValues(_FstnrManualModeRadioWgt, XmNset, False, NULL);
switch(_CrntModeItem)
{
case FSTNR_AUTO_MODE
{
XtVaSetValues(_FstnrAutoModeRadioWgt, XmNset, True, NULL);
// here you can call XmToggleButtonSetState with 3rd - Last Parameter = False
break;
}
case FSTNR_MANUAL_MODE
{
XtVaSetValues(_FstnrManualModeRadioWgt, XmNset, True, NULL);
// here you can call XmToggleButtonSetState with 3rd - Last Parameter = False
break;
}
default
{
cout << "
Warning!!!, Wrong Option in FstnrModelGUISetCurrentModeItemState() " << endl;
break;
}
}
}
Creation of Toggle Buttons
---------------------------
c = 0;
XtSetArg(arg[c], XmNrightAttachment, XmATTACH_POSITION); c++;
XtSetArg(arg[c], XmNrightPosition, Fstnr_ModeRadio_RightPos); c++; //80
XtSetArg(arg[c], XmNtopAttachment, XmATTACH_FORM); c++;
XtSetArg(arg[c], XmNbottomAttachment, XmATTACH_FORM); c++;
XtSetArg(arg[c], XmNleftAttachment, XmATTACH_POSITION); c++;
XtSetArg(arg[c], XmNleftPosition, Fstnr_ModeRadio_LeftPos); c++; //20
XtSetArg(arg[c], XmNorientation, XmHORIZONTAL); c++;
_FstnrModeRadioWgt = XmCreateRadioBox(_FstnrModeForm, "Radio Box", arg, c);
XtManageChild(_FstnrModeRadioWgt);
_FstnrAutoModeRadioWgt = XtVaCreateManagedWidget("Auto",
xmToggleButtonWidgetClass, _FstnrModeRadioWgt,
XmNindicatorSize, Fstnr_Radio_IndicatorSize,
NULL);
MList[FSTNR_AUTO_MODE].Index = FSTNR_AUTO_MODE;
MList[FSTNR_AUTO_MODE].FAList = this;
XtAddCallback(_FstnrAutoModeRadioWgt, XmNvalueChangedCallback, FstnrModeRadioToggledCB, &MList[FSTNR_AUTO_MODE]);
_FstnrManualModeRadioWgt = XtVaCreateManagedWidget("Manual",
xmToggleButtonWidgetClass, _FstnrModeRadioWgt,
XmNindicatorSize, Fstnr_Radio_IndicatorSize,
NULL);
MList[FSTNR_MANUAL_MODE].Index = FSTNR_MANUAL_MODE;
MList[FSTNR_MANUAL_MODE].FAList = this;
XtAddCallback(_FstnrManualModeRadioWgt, XmNvalueChangedCallback, FstnrModeRadioToggledCB, &MList[FSTNR_MANUAL_MODE]);
Forcing XmNset on toggle Buttons - equal to your reset
-------------------------------- ------------------
void SetCurrentModeItemState()
{
XtVaSetValues(_FstnrAutoModeRadioWgt, XmNset, False, NULL);
XtVaSetValues(_FstnrManualModeRadioWgt, XmNset, False, NULL);
switch(_CrntModeItem)
{
case FSTNR_AUTO_MODE
{
XtVaSetValues(_FstnrAutoModeRadioWgt, XmNset, True, NULL);
// here you can call XmToggleButtonSetState with 3rd - Last Parameter = False
break;
}
case FSTNR_MANUAL_MODE
{
XtVaSetValues(_FstnrManualModeRadioWgt, XmNset, True, NULL);
// here you can call XmToggleButtonSetState with 3rd - Last Parameter = False
break;
}
default
{
cout << "
Warning!!!, Wrong Option in FstnrModelGUISetCurrentModeItemState() " << endl;
break;
}
}
}
Believe me, Ragu, I have tried everything. That was my first try, since I didn`t actually want the activate callback to be called, but thought it might make a difference.
I HAVE GOOD NEWS THOUGH!!! I checked with a guy who frequently posts on the comp user`s group for Motif under Google - Fred L. Kleinschmidt at Boeing -- and he knew exactly what the problem was. I just tried it and this works under Linux. Here`s a snippet from his email to me
***********************************************************
Motif 2.2.1 introduced a bug in radio behavior, so you may have a version of Motif that has the bug. It causes the program to act as you describe - if you programmatically set buttonA when buttonB is currently set, the user must select some other button before buttonB can be selected by the user. Here is a workaround to use instead of calling XmToggleButtonSetState(w, True, True)
{
XEvent event;
event.xbutton.type = ButtonRelease;
event.xbutton.x_root = 0;
event.xbutton.y_root = 0;
XtCallActionProc(w,"Arm",&event,NULL,0)
XtCallActionProc(w,"Select",&event,NULL,0);
XtCallActionProc(w,"Disarm",&event,NULL,0);
}
***************************************************************
Ragu I have to tell you, though, that you do need to still call XmToggleButtonSetState(w, True, True); or else the widget thinks it`s deselected but still looks selected on the screen.
I have been trying things for 3 days now and am so happy it finally works!
Hopefully this information will help you and others, too.
i am happy that u got the solution , let me try this on my linux box, it has this problem and hope this solves .
hey thanks a lot julie for sharing this with me.
hope to learn more like this...
take care and have a wonderful day.
i will take the snippet for sure and try and let u know soon oka
The way that I got around this was to create a routine that creates the Radio Box and toggle buttons. Then I call the routine every time I need to reset the buttons, passing in the parent. Note that the routine must Destroy the old Radio Box before creating the new one. This can be done by setting the Radio Box to NULL in the define. After the first call to the routine the Radio Box will no longer be NULL; therefore, you know that you need to call XtDestroyWidget() [I think that`s right] before creating another. Of course, during the recreate the box disappear and reappears (however that is hardly noticeable).
I have written in about his problem before and I tried every solution that was provided; however, none of them worked. The above did, however. For some reason you can set the button you want selected at initial creation, but once selections have begun you can not seem to reset them.
I suppose the nightmares should really be about code that used to work now not working. Sounds like you`ve been bitten by the bug mentioned above. There are more recent versions available.
There are some other problems with the Motif model for radio buttons. The first to spring to mind is in jrsugar`s post above -- he didn`t realize that he was using an XmRowColumn. The XmRadioBox is an XmRowColumn with certain settings forced -- those that affect radio behavior. The second problem is that the radio behavior is buried in the XmRowColumn to begin with. Other toolkits, such as the Rt/Mt toolkit, instead let toggle buttons name a "tag"; the back-end software connects all toggles with that tag into a radio set. The layout of the toggles can then be not limited by what the radio box can maintain. Note that this mechanism can be grafted onto Motif.