Button functions not working

(I am a beginner in both Juce and C++)

I’m having issues updating text buttons using setButtonText and setToggleState in my own functions. The initial setup of the buttons works fine using these same functions, and everything works fine in the UI.

The strange part is that when including these functions within a buttonClicked callback, they work if the callback was triggered by me clicking a button in the UI, but not if the callback was triggered in my code using triggerClick. I am logging and can see that the callback is correctly executed by my triggerClick - so I am confused as to why I get different behaviour when this is called from a UI interaction versus manually.

Everything else about the buttons (set up as radio buttons) works fine when using the UI to trigger the buttons.

btn1.get()->setToggleState(true, dontSendNotification);

When testing, I created another button test1:

  • if I click test1 in the UI it will correctly update the btn1 toggle state
  • if I click test1 in my program manually using test1.get()->triggerClick(); the buttonClicked callback is called, but btn1 state is not toggled.
if (buttonThatWasClicked == test1.get()) {
        btn1.get()->setToggleState (true, dontSendNotification);
}

Any advice would be greatly appreciated.

Welcome @cfrapp,

can we go a step back and can you tell what you are trying to do?

The Button class unifies certain functionality for ALL possible buton like TextButton, CheckBox etc.
All buttons can be switched from click to toggle by setting setClickingTogglesState (true). This way one click will switch the button on and a second click turns it off again.

With that mode you don’t need (and shouldn’t) use any listener to toggle the state.

All Buttons can be a radio button by setting them to the same radio group ID setRadioGroupId (anyNumber). All buttons that are siblings and have the same ID anyNumber will become mutually exclusive.

And off-topic:
A std::unique_ptr implements the -> operator, so you don’t need to call .get():

btn1->setClickingTogglesState (true);

Good luck

1 Like

Thanks @daniel

I am using Juce to implement a basic radio button song selecter for another app. It has a C++ API which provides its own callbacks for when songs change.

I can get everything working when selecting songs using Juce GUI (calling the other program’s functions to select the song). But I can’t go the other way → syncing up the selected radio button in Juce GUI when the song change was initiated by the other app.

I naively thought that having the Juce button pointers public will allow me to update the buttons from the other app’s class. Where I am confused is that I can successfully call a custom function in my juce window class, but the updates to the buttons don’t work. Whereas if I call this same custom function from the Juce buttonClicked callback, then the buttons update correctly.

This is with all button functions, even SetButtonText. When my custom function is called from the Juce callback: all works; when my custom function is called from the other app’s class, the function is called, but the button updates don’t work.

I did end up replicating this with the Juce tutorial Radio Buttons and Checkboxes - so I suspect it’s my own limited C++ knowledge that is the culprit.

I think there is only a simple mistake:

When you call

btn1->setToggleState (true, dontSendNotification);

You specifically tell JUCE you don’t want anybody else to be notified of the change. But you DO want the radio group and stuff to react to the change, so try if changing it to sendNotification solves your problems:

btn1->setToggleState (true, sendNotification);
1 Like

Thanks, I did end up trying all notification types :slight_smile:

My reason for using dontSendNotification was because the song change was initiated already from the other app, so I only wanted the visual state of the button to change - not to call the Juce buttonClicked callback.

I think it’s something else, as I have the same issue using SetButtonText. I can’t seem to update any button programmatically outside of the buttonClicked callback - unless the function had been called from the buttonClicked callback.

Another thought would be, if you accidentally shadow the variable or create a copy somewhere, so you might not modify what you think you modify.

It’s similar to this scenario (I’m trying to replicate it in the tutorial example). If test() is called from the updateToggleState callback, then the button update works. But if I call test() from another part of my code, the button doesn’t update. I have used logging to show that test() is actually called.

    void updateToggleState (juce::Button* button, juce::String name)
    {
        if (button == &maleButton)
            test();
    }

    void test() {
        maleButton.setButtonText("Yes I am Male");
    }