disable widget and connect to a slot

  • Hi All,

    I've a basic question.
    I've a push button to enable/disable a widget and I'm connecting as follows.

     connect(ui->pushButton_One, &QPushButton::clicked, ui->widget_currentOne, &CurrentButtonOne::setEnabled);

    Is there a way to call another slot when the widget (widget_currentOne) is Disabled?

  • @viniltc
    Since I assume you don't get &QPushButton::clicked on a disabled widget, I presume you can use mousePressEvent/mouseReleaseEvent instead?

    Wait: you wrote

    when the widget (widget_currentOne) is Disabled

    So you mean when slot target widget is disabled, you want to call a different slot? Seems odd, but anyway: there isn't support for that, you do it in the receiving code. Don't forget you can use a lambda here to make it easy,

  • Lifetime Qt Champion

    @viniltc To me it is not clear what you want to do.
    Do you want to enable and disable the widget using the same button? Like toggling the enabled state of the widget?
    If so then simply:

    connect(ui->pushButton_One, &QPushButton::clicked, [this](){ ui->widget_currentOne->setEnabled(!ui->widget_currentOne->enabled()); });

  • @JonB @jsulm Thanks for your response :)

    @JonB said in disable widget and connect to a slot:

    So you mean when slot target widget is disabled, you want to call a different slot?

    yes, that's what I'm trying but seems I may have other options.

    This is what I'm doing at present:

    There is a pushbutton to enable a widget as follows:

    connect(ui->pushButton_currOnOne, &QPushButton::clicked, ui->widget_currentOne, &CurrentButtonOne::setEnabled);

    and this widget is connected to another slot to adjust a value:

     connect(ui->widget_currentOne, &CurrentButtonOne::getValue, this, &stageProgram::setCurrOnChannelOne);

    and the slot is:

    void stageProgram::setCurrOnChannelOne(unsigned int current_uA)
        tetra_grip_api::stimulation_set_current( m_channelOne, current_uA); // second argument I get as signal from the widget

    But what I now need if the widget is disabled the signal value should be 0 (meaning the current_uA = 0)

    I was thinking to call different slot and set current_uA = 0. Looks like it's not possible, can you think of an alternate way ?

  • @viniltc
    I'm not sure why some signal named getValue on a widget would want to cause a slot named setCurrOnChannelOne to be called, because "gets" on a widget are normally just read a value, period, but never mind.

    As I & @jsulm said, you can consider using lambdas to alter what slots are called and with what parameters. A slot does not have to be a fixed method, you can gain flexibility via a lambda. (You might want to read up on that in the docs.)

    I think the sort of thing you want here would be:

    connect(ui->widget_currentOne, &CurrentButtonOne::getValue,
            [this](unsigned int current_uA) { setCurrOnChannelOne(ui->widget_currentOne->enabled() ? current_uA : 0); } );

    See how we have written a little bit of code to call your setCurrOnChannelOne() explicitly (not just function address), having played with the parameter from the signal before passing it on?

    We could also use this technique to only call the slot on the signal selectively: if you didn't want it called at all when that widget is disabled you could have:

    connect(ui->widget_currentOne, &CurrentButtonOne::getValue,
            [this](unsigned int current_uA) { if (ui->widget_currentOne->enabled()) setCurrOnChannelOne(current_uA); } );

  • @JonB Thanks a lot.

    I tried as you suggested using lambda.

    connect(ui->widget_currentOne, &CurrentButtonOne::getValue,
            [this](unsigned int current_uA) { setCurrOnChannelOne(ui->widget_currentOne->isEnabled() ? current_uA : 0); } );

    But here, I'm not getting the expected when the widget is disabled (should pass 0 to slot)

    is this because the way I initialized the slot?

    Now the slot looks like this:

    void stageProgram::setCurrOnChannelOne(unsigned int current_uA)
        ui->label_11->setText(QString::number(current_uA)); //label to check the value

  • @viniltc
    Slot looks OK to me.

    You can see that at run-time my lambda-slot simply executes:

    setCurrOnChannelOne(ui->widget_currentOne->enabled() ? current_uA : 0);

    so if widget_currentOne that should pass on the current_uA parameter received from your CurrentButtonOne::getValue signal, else it passes on 0. Which looks right to me, unless I can't see the wood for the trees?

    As with anything, put in some debug statements:

    connect(ui->widget_currentOne, &CurrentButtonOne::getValue,
            [this](unsigned int current_uA) {
                qDebug() << "widget_currentOne->enabled(): " << ui->widget_currentOne->enabled();
                qDebug() << "current_uA: " << current_uA;
                setCurrOnChannelOne(ui->widget_currentOne->enabled() ? current_uA : 0);
            } );

    And I presume your CurrentButtonOne::getValue signal is correctly passing on the right value.

  • Lifetime Qt Champion


    Are you trying to implement some sort of Oscilloscope ?

  • @JonB Yes, the getValue is passing the correct value. But still the issue is lambda is not sending 0 when the widget is disabled.
    @SGaist it is a user interface for a 5 channel electrical stimulator, this is the stage where I set current for each channel

  • Lifetime Qt Champion

    Then I would highly recommend reconsidering your design.

    You should rather have one widget per channel that is able to fully manage it.

    Then do a proper management panel to configure the channels. If a channel is disabled then so should be the widgets that can modify them.

Log in to reply