I think, the best solution here would be to block signals from spinboxes, before changing their values in slots:
I usually use the helper class like this:
class SignalsBlocker
{
public:
SignalsBlocker(QObject* ptr):
_ptr(ptr)
{
_b = ptr->blockSignals(true);
}
~SignalsBlocker()
{
_ptr->blockSignals(_b);
}
private:
QObject* _ptr;
bool _b;
};
So you can write
void MainWindow::on_sbHeight_valueChanged(int arg1)
{
SignalsBlocker block(ui->sbWidth);
if (arg1 != 0) {
if (ui->radioRatio1->isChecked()) {
ui->sbWidth->setValue((arg1/8)*2);
//.....
}
void MainWindow::on_sbWidth_valueChanged(int arg1)
{
SignalsBlocker block(ui->sbHeight);
if (arg1 != 0) {
if (ui->radioRatio1->isChecked()) {
ui->sbHeight->setValue((arg1/2)*8);
//....
}
The straightforward solution one can provide is
void foo(QObject* object)
{
object->blockSignals(true);
// some stuff
object->blockSignals(false);
}
However, this solution is not correct: imagine the follwing situation
QObject* obj;
obj->blockSignals(true);
foo(obj);
//some other stuff
obj->blockSignals(false);
One could hope signals will be unblocked after some otherstuff
, but actually they will be unblocked inside foo
function, that is not intended behavior. That is why you should save block sate and then restore it.
But again, RAII helper class is the most convenient solution that reduces code complexity.
Also note,that your calculations with integers, like
(arg1/8)*2
are not accurate at all.
For example, let arg1 = 6
. Then arg1/8
is 0
, and (arg1/8)*2
results in 0
.
Just changing the order of calculations can increase accuracy:
(arg1 * 2) / 8
arg1 = 6
arg1 * 2 = 12
(arg1 * 2 / 8) = 1