Reputation: 3488
I have a code with a QDoubleSpinBox
ui->doubleSpinBoxExposure->setMinimum(0.001);
ui->doubleSpinBoxExposure->setMaximum(1000);
ui->doubleSpinBoxExposure->setSingleStep(1.0);
connect(ui->doubleSpinBoxExposure, SIGNAL(valueChanged(double)),
this, SLOT(OndoubleSpinBoxExposure_valueChanged(double)));
void WidgetCameraParameter::OndoubleSpinBoxExposure_valueChanged(double value)
{
if (!camera)
return;
if (camera->isOpen())
{
float exposure = static_cast<float>(value);
float cameraExposure;
camera->setExposure(exposure);
LOG_INFO() <<" setting exposure to " << value << " ms";
cameraExposure = camera->exposure();
LOG_INFO() <<" resulting exposure is " << cameraExposure << " ms";
}
}
The problem is, when I step up in the gui or down, this happens twice. The starting parameter is value = 2. StepUp calls this function with 3, and directly afterwards with 4. And I have no idea why.
The stack trace is not helpfull:
1 WidgetCameraParameter::OndoubleSpinBoxExposure_valueChanged widgetcameraparameter.cpp 311 0x406c17
2 WidgetCameraParameter::qt_static_metacall moc_widgetcameraparameter.cpp 110 0x40811f
3 QMetaObject::activate qobject.cpp 3771 0x12bc2e1
4 QMetaObject::activate qobject.cpp 3633 0x12bc575
5 QDoubleSpinBox::valueChanged moc_qspinbox.cpp 436 0x15e66190 6 QDoubleSpinBoxPrivate::emitSignals qspinbox.cpp 1112 0x15e663b2 7 QAbstractSpinBoxPrivate::setValue qabstractspinbox.cpp 1741 0x15e6174d 8 QAbstractSpinBox::stepBy qabstractspinbox.cpp 643 0x15e62aba 9 QAbstractSpinBox::timerEvent qabstractspinbox.cpp 1246 0x15e5ffea 10 QObject::event qobject.cpp 1232 0x12bc918
11 QWidget::event qwidget.cpp 9347 0x15d0c544 12 QAbstractSpinBox::event qabstractspinbox.cpp 795 0x15e65930 13 QApplicationPrivate::notify_helper qapplication.cpp 3727 0x15cc85ca 14 QApplication::notify qapplication.cpp 3690 0x15cd1f4f 15 QCoreApplication::notifyInternal2 qcoreapplication.cpp 1048 0x1295119
16 QCoreApplication::sendEvent qcoreapplication.h 234 0x12e4d87
17 QEventDispatcherWin32Private::sendTimerEvent qeventdispatcher_win.cpp 447 0x12e4d87
18 qt_internal_proc(HWND__ *, unsigned int, unsigned int, long) *16 qeventdispatcher_win.cpp 242 0x12e53d5
19 gapfnScSendMessage 0x771162fa 20 ?? 0x5c0f30
21 USER32!GetThreadDesktop 0x77116d3a 22 QEventDispatcherWin32Private::sendTimerEvent qeventdispatcher_win.cpp 456 0x12e4dc9
23 ?? 0x5c0f30
24 USER32!CharPrevW 0x771177c4 25 USER32!DispatchMessageW 0x7711788a 26 QEventDispatcherWin32::processEvents qeventdispatcher_win.cpp 629 0x12e4ae8
27 QWindowsGuiEventDispatcher::processEvents qwindowsguieventdispatcher.cpp 74 0x2496dab7 28 QEventLoop::processEvents qeventloop.cpp 136 0x12937c8
29 QEventLoop::exec qeventloop.cpp 214 0x1293c20
30 QCoreApplication::exec qcoreapplication.cpp 1336 0x129c30e
31 QGuiApplication::exec qguiapplication.cpp 1761 0x8461552
32 QApplication::exec qapplication.cpp 2901 0x15cc84a9 33 qMain main.cpp 28 0x40183d
34 WinMain *16 qtmain_win.cpp 104 0x4094c5
35 main 0x4179ad
Any idea how to debug this further?
EDIT: This only happens when I debug with breakpoints in the slot. Without the slot is only called once. The second call of the slot does not happen from any function within the slot function, but only after the slot has ended from the event loop.
You can loop at the complete code: https://github.com/pospiech/code/tree/master/libdev/devices/CameraViewer
Upvotes: 2
Views: 1468
Reputation: 125
It looks like you have a freezing gui-thread with your slot. You can try this code in your slot
void WidgetCameraParameter::OndoubleSpinBoxExposure_valueChanged(double value)
{
#define NUM_LOOPS 1000000000
qDebug() << value;
quint64 i = NUM_LOOPS;
while(i--);
}
To avoid this, you have to move to another thread an operation that consumes a lot of CPU time.
In debug mode its because of autorepeating timer. Try this code to disable autorepeating in debug and, i think, you`ll understand:
*.h
...
#ifdef QT_DEBUG
bool eventFilter(QObject *watched, QEvent *event) override;
#endif
...
*.c
...
ui->setupUi(this);
#ifdef QT_DEBUG
ui->doubleSpinBoxExposure->installEventFilter(this);
#endif
...
#ifdef QT_DEBUG
bool WidgetCameraParameter::eventFilter(QObject *watched, QEvent *event)
{
QDoubleSpinBox *castSBox = static_cast<QDoubleSpinBox*>(watched);
if(castSBox && event->type()==QEvent::Timer)
{
QTimerEvent *tEvent = static_cast<QTimerEvent*>(event);
if(tEvent)
qDebug() << "<--QEvent::Timer-->" << tEvent->timerId();
return true;
}
return QObject::eventFilter(watched,event);
}
#endif
Upvotes: 0
Reputation: 10047
Looking at the QStyle::StyleHint
enum, there is an interesting SH_SpinBox_ClickAutoRepeatThreshold
constant. You can check its current value for your spin box, like this:
qDebug() << ui->doubleSpinBoxExposure->style()->styleHint(QStyle::SH_SpinBox_ClickAutoRepeatThreshold);
This generally returns 500
, which is the number of milliseconds after which the auto repeat gets triggered (i.e. if the user holds the mouse press on the up
spin button for longer than that threshold, the spin box value will start increasing continuously).
To see if you have a timing issue, try changing that value, using a custom QStyle
class like this:
#include <QProxyStyle>
class MyStyle : public QProxyStyle
{
public:
int styleHint(StyleHint stylehint, const QStyleOption *opt, const QWidget *widget, QStyleHintReturn *returnData) const
{
if(stylehint == QStyle::SH_SpinBox_ClickAutoRepeatThreshold)
{
return 2000; //2 seconds threshold
}
return QProxyStyle::styleHint(stylehint, opt, widget, returnData);
}
};
and setting an instance of it to the spin box style:
ui->doubleSpinBoxExposure->setStyle(new MyStyle());
Now it takes a lot (two long seconds) before the auto repeat gets triggered, and your issue should be gone, accordingly.
Upvotes: 3