I've been noticing an odd behavior with QSlider, which can be reproduced whenever slider widgets have different width, eg. being resized. Is it a problem with my signals? if so, how would I go about updating slider2 when slider1 has been updated, without affecting the width of the slider?
The problem:
Changing the width of slider1, repaints slider2 to look the same, but repositioning slider2 manually will show that the length hasn't been changed, making it look like a glitch. Any ideas what's going on here or if it's a bug?
Expected behavior:
The sliders should not have any connection to each other regarding their layout, the only change I'd expect to see, is the knob being moved the corresponding position on the resized widget, not the exact same position.
Actual behavior:
The knob moves to the exact same position on the widget it signals to, instead of an offset position that should match its new width.
The following example was compiled using: Qt 5.12.3 on Mac OS 10.14.5
Example
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QHBoxLayout>
#include <QSlider>
#include <QMainWindow>
#include <QDebug>
#include <QDockWidget>
class DockSliderWidget : public QDockWidget
{
Q_OBJECT
public:
DockSliderWidget(QWidget* parent = nullptr)
: QDockWidget(parent)
{
QWidget* container = new QWidget(this);
QHBoxLayout* hBoxLayout = new QHBoxLayout();
mSlider = new QSlider(Qt::Horizontal, this);
mSlider->setMinimum(0);
mSlider->setMaximum(100);
connect(mSlider, &QSlider::valueChanged, this, &DockSliderWidget::valueChanged);
hBoxLayout->addWidget(mSlider);
container->setLayout(hBoxLayout);
setWidget(container);
}
void changeValue(qreal value)
{
qDebug() << value;
QSignalBlocker b(mSlider);
mSlider->setValue(value);
}
Q_SIGNALS:
void valueChanged(qreal value);
private:
QSlider* mSlider = nullptr;
};
class DockSliderWidget;
class Widget : public QMainWindow
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr)
: QMainWindow(parent)
{
sliderWidget1 = new DockSliderWidget(parent);
sliderWidget2 = new DockSliderWidget(parent);
connect(sliderWidget1, &DockSliderWidget::valueChanged, sliderWidget2, &DockSliderWidget::changeValue);
connect(sliderWidget2, &DockSliderWidget::valueChanged, sliderWidget1, &DockSliderWidget::changeValue);
addDockWidget(Qt::DockWidgetArea::RightDockWidgetArea, sliderWidget1);
addDockWidget(Qt::DockWidgetArea::LeftDockWidgetArea, sliderWidget2);
}
~Widget()
{
}
private:
DockSliderWidget* sliderWidget1;
DockSliderWidget* sliderWidget2;
};
#endif // WIDGET_H