문제
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)));
}
해결책
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.
다른 팁
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,