PDA

View Full Version : using one signal to update multiple multiple controls



henryjoye
12th December 2011, 23:12
I have multiple QDoubleSpinBox in a dialog as follows:

QDoubleSpinBox *qsb_fov_min_x;
QDoubleSpinBox *qsb_fov_max_x;
QDoubleSpinBox *qsb_fov_min_y;
QDoubleSpinBox *qsb_fov_max_y;
QDoubleSpinBox *qsb_fov_min_z;
QDoubleSpinBox *qsb_fov_max_z;
QDoubleSpinBox *qsb_fov_step_x;
QDoubleSpinBox *qsb_fov_step_y;
QDoubleSpinBox *qsb_fov_step_z;

When the value in each QDoubleSpinBox is changed, I do some updates in update(). This works fine for me. Now I add one QPushButton as a "reset" button. When I click this reset button, I need to reset values of all QDoubleSpinBox to their own default values. So I connect button's click() signal to my own slot resetFOVDIM(). When I run this program and click the "reset" button, I found that not all QDoubleSpinBox values are set to their default values at the same time, but only one QDoubleSpinBox value is set on each clicking. I need to click the "reset" button nine times to reset all nine QDoubleSpinBox values.

Could anyone show me what the problem is in my code and how to reset all values one time when I click the "reset" button? Many thanks!


Here are code snippets:

Setup_Dialog::void Setup_Dialog()
{
// other initializations
......

// signal / slot connection
connect(qsb_fov_min_x, SIGNAL(valueChanged(double)), this, SLOT(update()));
connect(qsb_fov_max_x, SIGNAL(valueChanged(double)), this, SLOT(update()));
connect(qsb_fov_min_y, SIGNAL(valueChanged(double)), this, SLOT(update()));
connect(qsb_fov_max_y, SIGNAL(valueChanged(double)), this, SLOT(update()));
connect(qsb_fov_min_z, SIGNAL(valueChanged(double)), this, SLOT(update()));
connect(qsb_fov_max_z, SIGNAL(valueChanged(double)), this, SLOT(update()));

connect(qsb_fov_step_x, SIGNAL(valueChanged(double)), this, SLOT(update()));
connect(qsb_fov_step_y, SIGNAL(valueChanged(double)), this, SLOT(update()));
connect(qsb_fov_step_z, SIGNAL(valueChanged(double)), this, SLOT(update()));

connect(reset, SIGNAL(clicked()), this, SLOT(resetFOV()));
}

void Setup_Dialog::resetFOV()
{
fov_min_x = -150.0;
fov_max_x = 150.0;
fov_step_x = 1.0;

fov_min_y = -150.0;
fov_max_y = 150.0;
fov_step_y = 1.0;

fov_min_z = 50.0;
fov_max_z = 60.0;
fov_step_z = 1.0;


// set values
qsb_fov_min_x->setValue(fov_min_x);
qsb_fov_max_x->setValue(fov_max_x);
qsb_fov_step_x->setValue(fov_step_x);

qsb_fov_min_y->setValue(fov_min_y);
qsb_fov_max_y->setValue(fov_max_y);
qsb_fov_step_y->setValue(fov_step_y);

qsb_fov_min_z->setValue(fov_min_z);
qsb_fov_max_z->setValue(fov_max_z);
qsb_fov_step_z->setValue(fov_step_z);

}

void Setup_Dialog::update()
{
// do other updates
}

ChrisW67
13th December 2011, 01:32
When you call

qsb_fov_min_x->setValue(fov_min_x)
in resetFOV() you will cause update() to run via the valueChanged() signal. If update() changes any of fov_* members variables, for example reading all the slider values into the variables, then the next call to setValue() may not be using the value you think it is.

henryjoye
13th December 2011, 02:46
When you call

qsb_fov_min_x->setValue(fov_min_x)
in resetFOV() you will cause update() to run via the valueChanged() signal. If update() changes any of fov_* members variables, for example reading all the slider values into the variables, then the next call to setValue() may not be using the value you think it is.

Many thanks! yes, you are right. update() changes some fov_* variables. in this case, could you mind to show me any cues on how to solve this problem? Thank you very much!

ChrisW67
13th December 2011, 03:15
Two approaches come to mind:

In resetFOV() set the slider widgets with the default values (as literals) and allow the update() function to propagate the change into the member variables.
Dispense with the member variables altogether and use the widgets as the only storage of the values... no need to maintain sync.

henryjoye
13th December 2011, 04:24
Two approaches come to mind:

In resetFOV() set the slider widgets with the default values (as literals) and allow the update() function to propagate the change into the member variables.
Dispense with the member variables altogether and use the widgets as the only storage of the values... no need to maintain sync.

Many thanks! I may re-interprete your solutions:
o The first one: I do not completely understand this solution. It seems that my current version is like that.
o The second one: this means that each widget has a separate slot function for the corresponding signal, but not use one slot for all widgets. Am i right?
Thank you!

d_stranz
13th December 2011, 04:27
Or simply add a Boolean "resetInProgress" member variable to Setup_Dialog that gets set to true on entry into resetFOV() and set to false on exit. In update(), check to see if resetInProgress == true, and ignore the signal from the spin box if it is.

ChrisW67
13th December 2011, 04:39
Many thanks! I may re-interprete your solutions:
o The first one: I do not completely understand this solution. It seems that my current version is like that.

You would remove the lines from resetPOV() that set the member variables and change the setValue() lines.


void Setup_Dialog::resetFOV()
{
// set values
qsb_fov_min_x->setValue(-150.0);
qsb_fov_max_x->setValue(50.0);
qsb_fov_step_x->setValue(1.0);

qsb_fov_min_y->setValue(-150.0);
qsb_fov_max_y->setValue(150.0);
qsb_fov_step_y->setValue(1.0);

qsb_fov_min_z->setValue(50.0);
qsb_fov_max_z->setValue(60.0);
qsb_fov_step_z->setValue(1.0);
}



o The second one: this means that each widget has a separate slot function for the corresponding signal, but not use one slot for all widgets. Am i right?
Thank you!
Your current arrangement doesn't know or care which slider changed; update() reads/works with the current state of all of them anyway. This need not change except that you don't need to read each slider and stash it into a variable... everywhere you previously used the variable you would directly use the slider value. It really depends on how the current member variables are used as to whether this is feasible.

henryjoye
13th December 2011, 15:19
You would remove the lines from resetPOV() that set the member variables and change the setValue() lines.


void Setup_Dialog::resetFOV()
{
// set values
qsb_fov_min_x->setValue(-150.0);
qsb_fov_max_x->setValue(50.0);
qsb_fov_step_x->setValue(1.0);

qsb_fov_min_y->setValue(-150.0);
qsb_fov_max_y->setValue(150.0);
qsb_fov_step_y->setValue(1.0);

qsb_fov_min_z->setValue(50.0);
qsb_fov_max_z->setValue(60.0);
qsb_fov_step_z->setValue(1.0);
}


Your current arrangement doesn't know or care which slider changed; update() reads/works with the current state of all of them anyway. This need not change except that you don't need to read each slider and stash it into a variable... everywhere you previously used the variable you would directly use the slider value. It really depends on how the current member variables are used as to whether this is feasible.

Thank you very much! Both ChrisW67's solution and d_stranz's solution work. Many thanks!