Skip to main content
franck23
Associate III
February 17, 2021
Question

Setting RadioButton state without triggering action.

  • February 17, 2021
  • 9 replies
  • 3644 views

Hi,

I have 3 radio-buttons in a custom container which is present on several screens.

I would like the radio-buttons to keep their states between when switching screens.

I have the radio-buttons states reported to the model every time a button is pressed and when the screen changes, the new active view fetches the radio-button state.

However, I do not see a function to update a radio-button state without triggering the button action.

Is there such a function?

9 replies

MM..1
Chief III
February 17, 2021

void Screen1View::setupScreen()
{
 Screen1ViewBase::setupScreen();
 
 radioButtonGroup1.setSelected(radioButton1);
 
}

 maybe better is create array for objects radio and store index, because call need pointer to object.

franck23
franck23Author
Associate III
February 17, 2021

Thanks, but the problem with setSelected is that it triggers the button action: the radioButtonSelectedCallbackHandler is called.

I am looking for a way to set the radio buttons without triggering the callback Handler.

If there is no way to do it directly, I will set a flag to ignore the callback.

Romain DIELEMAN
ST Employee
February 18, 2021

Hi,

What you could do is modify the setSelected function in RadioButton.cpp file in the Middlewares folder or create another function to handle this situation.

/Romain

franck23
franck23Author
Associate III
February 17, 2021

Also, when using radioButtonGroup1.setSelected(radioButton1), the radioButtonSelectedCallbackHandler get called twice.

I haven't been able to trace what is triggering the second call but this looks like a bug.

Romain DIELEMAN
ST Employee
February 18, 2021

Interesting, I will investigate. Could you share a project where this happens ?

/Romain

franck23
franck23Author
Associate III
February 18, 2021

Hi Romain, thanks for looking into it.

I do have a sample project to demonstrate the issue, but it looks like the forum file attachment feature is disabled.

The attachment icon next to the picture icon is greyed out.

Or maybe I am looking at the wrong place?

BTW, is there another way to keep the custom container synchronized between screens?

Most of the time, it makes sense for the widgets to stay in the same state between screens.

franck23
franck23Author
Associate III
February 18, 2021

@Romain DIELEMAN​ 

OK, just found the attachment icon...

The attached project is derivated from the TouchGFX Designer RadioButton Example.

It was tested with the simulator and on a discovery board with the same results.

There is a counter which is incremented every time the radioButton2Selected() get called.

Clicking on button1 execute radioButtonGroup.setSelected(radioButton2);

If radiobutton2 is clicked, the counter increments by 1 (normal behavior)

If button1 is clicked, radioButton2Selected() gets called twice, and the counter increments by 2 (I would expect only one callback).

MM..1
Chief III
February 18, 2021

Why you define callbacks in base code, when i create screen with radio my code is

/*********************************************************************************/
/********** THIS FILE IS GENERATED BY TOUCHGFX DESIGNER, DO NOT MODIFY ***********/
/*********************************************************************************/
#include <gui_generated/screen1_screen/Screen1ViewBase.hpp>
#include <touchgfx/Color.hpp>
#include "BitmapDatabase.hpp"
 
Screen1ViewBase::Screen1ViewBase()
{
 
 __background.setPosition(0, 0, 800, 480);
 __background.setColor(touchgfx::Color::getColorFrom24BitRGB(0, 0, 0));
 
 toggleButton1.setXY(336, 193);
 toggleButton1.setBitmaps(touchgfx::Bitmap(BITMAP_BLUE_TOGGLEBARS_TOGGLE_ROUND_LARGE_BUTTON_OFF_ID), touchgfx::Bitmap(BITMAP_BLUE_TOGGLEBARS_TOGGLE_ROUND_LARGE_BUTTON_ON_ID));
 
 radioButton1.setXY(356, 43);
 radioButton1.setBitmaps(touchgfx::Bitmap(BITMAP_BLUE_CHECK_BUTTONS_CHECK_MARK_INACTIVE_ID), touchgfx::Bitmap(BITMAP_BLUE_CHECK_BUTTONS_CHECK_MARK_PRESSED_ID), touchgfx::Bitmap(BITMAP_BLUE_CHECK_BUTTONS_CHECK_MARK_ACTIVE_ID), touchgfx::Bitmap(BITMAP_BLUE_CHECK_BUTTONS_CHECK_MARK_NORMAL_ID));
 radioButton1.setSelected(false);
 radioButton1.setDeselectionEnabled(false);
 
 radioButton2.setXY(356, 104);
 radioButton2.setBitmaps(touchgfx::Bitmap(BITMAP_BLUE_CHECK_BUTTONS_CHECK_MARK_INACTIVE_ID), touchgfx::Bitmap(BITMAP_BLUE_CHECK_BUTTONS_CHECK_MARK_PRESSED_ID), touchgfx::Bitmap(BITMAP_BLUE_CHECK_BUTTONS_CHECK_MARK_ACTIVE_ID), touchgfx::Bitmap(BITMAP_BLUE_CHECK_BUTTONS_CHECK_MARK_NORMAL_ID));
 radioButton2.setSelected(true);
 radioButton2.setDeselectionEnabled(false);
 
 add(__background);
 add(toggleButton1);
 add(radioButton1);
 add(radioButton2);
 radioButtonGroup1.add(radioButton1);
 radioButtonGroup1.add(radioButton2);
}
 
void Screen1ViewBase::setupScreen()
{
 
}

no callbacks here...

place this in view setup code after change selected states

radioButtonGroup.setRadioButtonSelectedHandler(radioButtonSelectedCallback);

franck23
franck23Author
Associate III
February 18, 2021

The callback defined in the base file has been generated using TouchGFX designer.

The code I have added is in the MainView.cpp.

MM..1
Chief III
February 18, 2021

As i write when you plan change state against designer states, without call callback, then you can dont generate callbacks to base file, and do it yourself in setup code ...

maybe too is possible redefine callback to null , set new group state and reaply original callback, but this i dont try.

MPast.1
Senior
February 10, 2025

Hi all,

I have the same problem (I'm using 4.24.0 version):

I have a lot of screens with radiobutton, And at at startup I need to change the selections due to user configuration.

But everytime I call "setSelected" the relative action is called and this trigger wrong behaviour on my code

I suggest in the next touchgfx release to insert a method similar to "forcestate" to upgrade the radiobutton state without generate action.

I would like to avoid to delete the callback in realtime and after change the status re-enabled them.

Associate II
January 29, 2026

Hello,

@MPast.1, you are the latest comment in this thread about the double firing of the callback function, did you manage to solve this issue?
in my application I'm using the setSelected function of the radio button and not of the radio button group, I manage to call the callback function only once as i wanted but since it wasn't the setSeclted function of the radio button group it didn't felt right. if you solved this, it would be kind of you to share the solution.

Thank you and best regards

MPast.1
Senior
January 29, 2026
HI H_Drx ,
in my project the "setSelected" function was used to load the right
values at screen startup to show the right settings on the various
control, before the screen begin show.
(in my case, every radio button callbacks set a value ON/OFF into some
flags and sent a message with the updated value to another device by a
UART).
My trick was to block for 1 seconds the message out from the uart at the
screen startup, to allow the screen to load the value and draw the
update status on various screen objects.
A simple flag is set to ONE at screen startup, block the uart (for 1
second) and then is set to ZERO when time is elapsed.
All others interaction, when time is expired with the radio buttons are
correctly managed after this "simple startup mask system".
This choose was taken to made to be more flexible and more compatible
with new or old version of TouchGFX, avoid to edit the original
framework files.
This trick not solved the problem but fake for a moment the radiobuttons
interactions. (others object, doesn't call the relative callback when
you set the initial value, so this problem is not visible to all).
Hope this trick can help you. If you discover an improvement on the
management, please write to me). Thanks.
Associate II
February 2, 2026

Hi @MPast.1 
I believe by saying "setSelected", you mean the function in the radio button group, because that one fires the callback twice, but if you try to use the "setSelected" of the radio button (not the group), that will fire the callback only once.
and if you set a counter depends on how many things you have to configure and when the counter reached that number then you can send the UART, no timer needed here, well, this depends on your architecture for sure. and this didn't solve the original problem,
this is the "setSelected" function of the RadioButton group

 virtual void setSelected(RadioButton& radioButton)
 {
 radioButton.setSelected(true);
 radioButtonClickedHandler(radioButton);
 }

as you can see, it already call the "setSelected" function of the radio button itself, and also call the click handler that will set the select option to other radio button to false and then run a call back, that call back will also fire the same "setSelected" function of radio button that have been fired, so, this is why it fires twice.

 virtual void radioButtonClickedHandler(const AbstractButton& radioButton)
 {
 // Deselect other radio buttons
 for (uint16_t i = 0; i < size; i++)
 {
 if (radioButtons[i] != &radioButton)
 {
 if (radioButtons[i]->getSelected())
 {
 radioButtons[i]->setSelected(false);
 }
 }
 }

 if (radioButtonSelectedCallback && radioButtonSelectedCallback->isValid())
 {
 radioButtonSelectedCallback->execute(radioButton);
 }
 }


I don't know what is the correct initialization i should do to make it fire only once. not sure if this is a bug or we shouldn't use the setSelect of radio button group at all. in the end, i just used the setSelect of each radio button for my dynamic configuration.