3

i have a problem with radio button.

I've created a groupbox with two radio buttons and set it exclusive so when one is checked the other one is unchecked.

when i check one it connects to a slot that as a function so it does an action, more specifically change the scale and transform the value from a Slider.

the problem is when i clicked by mistake the already checked button, because even if it already checked it still connects to the function and the value of the slider is changed again, which i don't want.

here's the code from them:

//Conect change from MM or PIXEL, making the change in the scale
  connect(ui->radioButton, SIGNAL(pressed())), this, SLOT(mm()));
  connect(ui->radioButton_2, SIGNAL(pressed()), this, SLOT(pixel()));

is there a way to block it when it has been already checked before?

I'll post here the mm() and pixel() functions:

// Function to transform the slider scale from pixel to mm
void planevolume::mm()
{
    // Set the sliders ranges and connections
    // X Slider
      double xvaluem=ui->Slider->value();
      ui->Slider->setRange(xmin, xmax/(256.0/3.0), 1.0/(256.0/3.0));
      ui->Slider->setValue(xvaluem/(256.0/3.0));
      ui->Slider->setScale(xmin, (xmax+1.0)/(256.0/3.0), ((xmax+1.0)/16.0)/(256.0/3.0));
      connect(ui->Slider, SIGNAL(valueChanged(double)), ui->lcdNumber, SLOT(display(double)));

    // Y Slider
      double yvaluem=ui->Slider_2->value();
      ui->Slider_2->setRange(ymin, ymax/(512.0), 1.0/(512.0));
      ui->Slider_2->setValue(yvaluem/(512.0));
      ui->Slider_2->setScale(ymin, (ymax+1.0)/512.0, (((ymax+1.0)/16.0)/512.0));
      connect(ui->Slider_2, SIGNAL(valueChanged(double)), ui->lcdNumber_2, SLOT(display(double)));

    // Z Slider
      double zvaluem=ui->Slider_3->value();
      ui->Slider_3->setRange(zmin, zmax/(64.0/3.0), 1.0/(64.0/3.0));
      ui->Slider_3->setValue(zvaluem/(64.0/3.0));
      ui->Slider_3->setScale(zmin, (zmax+1.0)/(64.0/3.0),(((zmax+1.0)/16.0)/(64.0/3.0)));
      connect(ui->Slider_3, SIGNAL(valueChanged(double)), ui->lcdNumber_3, SLOT(display(double)));
}

// Function to transform the slider scale from mm to pixel
void planevolume::pixel()
{
    // Set the sliders ranges and connections
    // X Slider
      double xvaluep=ui->Slider->value();
      ui->Slider->setRange(xmin, xmax, 1.0);
      ui->Slider->setValue(xvaluep*(256.0/3.0));
      ui->Slider->setScale(xmin, xmax+1.0, (xmax+1.0)/16.0);
      connect(ui->Slider, SIGNAL(valueChanged(double)), ui->lcdNumber, SLOT(display(double)));

    // Y Slider
      double yvaluep=ui->Slider_2->value();
      ui->Slider_2->setRange(ymin, ymax, 1.0);
      ui->Slider_2->setValue(yvaluep*(512.0));
      ui->Slider_2->setScale(ymin, ymax+1.0, (ymax+1.0)/16.0);
      connect(ui->Slider_2, SIGNAL(valueChanged(double)), ui->lcdNumber_2, SLOT(display(double)));

    // Z Slider
      double zvaluep=ui->Slider_3->value();
      ui->Slider_3->setRange(zmin, zmax, 1.0);
      ui->Slider_3->setValue(zvaluep*(64.0/3.0));
      ui->Slider_3->setScale(zmin, zmax+1.0, (zmax+1.0)/16.0);
      connect(ui->Slider_3, SIGNAL(valueChanged(double)), ui->lcdNumber_3, SLOT(display(double)));
}
Daniel Hedberg
  • 5,677
  • 4
  • 36
  • 61
SamuelNLP
  • 4,038
  • 9
  • 59
  • 102

2 Answers2

6

Instead of using the pressed() signal you might try to use the toggled(bool) signal. This signal is only emitted if the button changes state. Take a look at: http://doc.qt.io/qt-4.8/qabstractbutton.html#toggled

EDIT: If both buttons are connected to toggled(bool), then checking one will uncheck the other and also trigger the signal. But note that the signal has a bool that gives the new state of the button. Your slots must also have this bool parameter, i.e., in your case you need to rewrite your slots as void planevolume::mm(bool on) and void planevolume::pixel(bool on).

Once you have done this, you can simply check the value of the parameter. If it is false it means that the button was checked and now has just been unchecked. Then, the first line of both your functions can be as simple as

if (!on) return;

meaning, that if the radio button has just been unchecked, do not do anything, just go away.

Bowdzone
  • 3,827
  • 11
  • 39
  • 52
rpsml
  • 1,486
  • 14
  • 21
  • but when i check one the other one gets unchecked. that will send the signal too right? – SamuelNLP Aug 24 '12 at 15:45
  • I've updated my post with the mm() and pixel() functions so you can see that with toggled() signal the value from the slider is changed. – SamuelNLP Aug 24 '12 at 15:54
  • Yes, if both buttons are connected to `toggled` then they will. But see edit in my answer. – rpsml Aug 24 '12 at 15:59
2

I think the best option is to store a int value related to which option box is selected. Each time you click on an option box, check if it is already selected by using the variable, and then decide.

Regards,

Didac Perez Parera
  • 3,734
  • 3
  • 52
  • 87
  • I tried to do so but it then changes my value. for example, if it is in mm scale and the value is 5, if i click in mm it should do nothing, but the value changes. – SamuelNLP Aug 24 '12 at 13:40
  • like this? bool check1 = ui->radioButton->isChecked(); bool check2 = ui->radioButton_2->isChecked(); if (check1 == FALSE) { connect(ui->radioButton, SIGNAL(clicked()), this, SLOT(mm())); } if (check2 == FALSE) { connect(ui->radioButton_2, SIGNAL(clicked()), this, SLOT(pixel())); } ? it still does not work. – SamuelNLP Aug 24 '12 at 14:04