I have a custom QDialog with a set of custom sliders (i.e., QWidgets each consisting of a slider and an associated label) on it. In essence, this dialog is used to change the coordinates of an object in a 3D scene by adjusting the sliders for each dimension.
Currently, the QDialog itself stores a pointer to the scene object it modifies. Thus, the slot that takes care of object movement when a slider emits valueChanged
is also part of the QDialog class. Since it has no way of knowing which slider was moved, the movement function (rather inefficiently) just loops through all of the sliders on the dialog, gathers their values, and assigns a new configuration to the 3D object.
Ideally, only the dimension that changed would have to be re-assigned when a slider is moved. So I tried using QSignalMapper to identify each slider with a numerical index. This would require the ability to send a valueChanged
signal with two parameters: one identifying the sender slider, and one giving the new value itself. Unfortunately, as I learned here, QSignalMapper can't do this.
Another way to get the functionality I want would perhaps be to use the sender()
method. But, according to the documentation, that's bad practice--it violates the principle of modularity.
I can think of a couple of other solutions: allow the custom slider class to store its parent dialog (seems bad in the same say that sender()
is bad), or maybe even store the movable object itself as a static member of the custom slider class instead of (non-statically/as it is now) in the overall dialog.
Which of these approaches, if any, would be the best way to go here? What alternatives should I consider?
Possible solution is connect QSlider signal sliderReleased()
, emitted when the user releases the slider with the mouse, with QSignalMapper map()
and store sliders id with pointer on some list. When value has hanged, QDialog could emit another signal with information of slider id and new value.
QSignalMapper *mapper = new QSignalMapper(this);
connect(slider_0, SIGNAL(sliderReleased()), mapper, SLOT(map()));
mapper->setMapping(slider_0, 0);
tab_s[0] = slider_0;
connect(slider_1, SIGNAL(sliderReleased()), mapper, SLOT(map()));
mapper->setMapping(slider_1, 1);
tab_s[1] = slider_1;
connect(slider_2, SIGNAL(sliderReleased()), mapper, SLOT(map()));
mapper->setMapping(slider_2, 2);
tab_s[2] = slider_2;
connect(mapper, SIGNAL(mapped(int)),
this, SLOT(checkSlider(int)));
and in some slot:
void SomeDialog::checkSlider(int id)
{
emit valueChanged(id, tab_s[id]->value());
}