PDA

View Full Version : Qt Creator slot valueChanged(double) of doubleSpinBox called twice if breakpoint is set



Marco W.
13th March 2013, 14:49
Hi there,

I created a simple GUI Application using QT Creator 2.6 and MSVC2010 with CDB on a Win7 SP1 32-Bit system.

The QUI was created by QT Designer and has a doubleSpinBox. I setup the slot
valueChanged(double) of the doubleSpinBox. The slot is connected via

connectSlotsByName.

Everything works fine, but if I set a breakpoint in the slot

doubleSpinBox_valueChanged(double arg1)
{
}

there is a strange behaviour:

On a click on the arrows of the doubleSpinbox the slot
doubleSpinBox_valueChanged(double arg1) is called TWICE and of course the value-property of the doubleSpinBox is incremented/decremented twice!
I verified this by adding a
qDebug << "doubleSpinBox_valueChanged hit" to the slot.




Is this a known issue?

Thanks for your help in advance!

wysota
14th March 2013, 02:01
valueChanged() signal does not cause anything to be incremented or decremented. Could you explain better what you mean?

Marco W.
14th March 2013, 09:31
Hi wysota,

sorry if didn't make things clear. I will try to do it better:

I set a breakpoint in the slot valueChanged(double) of the doubleSpinBox. When I debug my GUI application and I click on the arrow-up-icon of the doubleSpinbox, then the breakpoint in the valueChanged(double)-Slot is hit and the old value is incremented as it should. But by clicking on F5 to continue the debugging, the breakpoint is hit again and the value of the doubleSpinBox is incremented again, i.e. twice!
As I sad, I also added a qDebug << "doubleSpinBox_valueChanged hit" in the valueChanged(double)-Slot and the message appears twice in the debugger output!

This happens only if a breakpoint is set in the valueChanged(double)-Slot. When I debug my GUI application without setting a breakpoint in the Slot, then by clickung on the arrow-up-icon the value is incremented only once and of course my qDebug-Message (as menitioned before) appears only once.

I hope that things became more clear.
Thanks for your help!

wysota
14th March 2013, 09:45
I set a breakpoint in the slot valueChanged(double) of the doubleSpinBox.
There is no such slot. valueChanged() is a signal. Make up your mind -- are you setting a breakpoint in the valueChanged() signal in QDoubleSpinBox or in a on_doubleSpinBox_valueChanged slot connected to that signal?

Marco W.
14th March 2013, 11:41
Oh, ok maybe I mixed it up.

I created a slot for the valueChanged() signal by right-clicking on the doubleSpinBox and selecting "Go to slot..." in QT Designer. The corresponding Signal and Slot are connected via QMetaObject::connectSlotsByName(MainWindow). This happens in the header file for the GUI (created by QT Designer).

So, in fact, it is the on_doubleSpinBox_valueChanged(double arg1) slot where I set my breakpoint.

Sorry for this inaccuracy and again thanks for helping me.

wysota
14th March 2013, 12:34
In that case it is not possible that the slot is executed twice if you set a breakpoint on it. If the slot is executing twice then it means you have two connections to it.

Marco W.
14th March 2013, 12:48
Well, but the slot is executed twice (and the value of the QdoubleSpinBox is incremented twice), if I set a breakpoint on it. I verified this by adding the qDebug() and printing a message to the debugger output.

If there is no breakpoint set, then the message is printed only once (and the value of the QdoubleSpinBox is incremented only once).


Is it possible that my Debugging Setup has some problems? Sometimes I get a message like:

*** WARNING: Unable to verify checksum for C:\Qt\Qt5.0.1\5.0.1\msvc2010\lib\Qt5Cored.dll
*** WARNING: Unable to verify checksum for C:\Qt\Qt5.0.1\5.0.1\msvc2010\lib\Qt5Widgetsd.dll
*** WARNING: Unable to verify checksum for C:\Qt\Qt5.0.1\5.0.1\msvc2010\lib\Qt5Guid.dll
*** WARNING: Unable to verify checksum for C:\Qt\Qt5.0.1\5.0.1\msvc2010\plugins\platforms\qwi ndowsd.dll

or

*** WARNING: Unable to verify checksum for MyApplicationName.exe

or (because I'm doing some openCV stuff)

*** WARNING: Unable to verify checksum for C:\opencv243\build\x86\vc10\bin\opencv_highgui243d .dll
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\opencv243\build\x86\vc10\bin\opencv_highgui243d .dll -
*** WARNING: Unable to verify checksum for C:\Qt\Qt5.0.1\5.0.1\msvc2010\lib\Qt5Guid.dll
*** WARNING: Unable to verify checksum for C:\Qt\Qt5.0.1\5.0.1\msvc2010\lib\libGLESv2d.dll
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Qt\Qt5.0.1\5.0.1\msvc2010\bin\icuuc49.dll -
*** WARNING: Unable to verify checksum for MyApplicationName.exe

Thanks

wysota
14th March 2013, 14:29
Well, but the slot is executed twice (and the value of the QdoubleSpinBox is incremented twice), if I set a breakpoint on it. I verified this by adding the qDebug() and printing a message to the debugger output.
That's no proof. Show me the backtrace which shows that the slot is called twice.

Marco W.
15th March 2013, 14:40
Hm, I'd like to, but I don't have a clue how to do that. Please, could you give a link / tutorial / some advice how to do a backtrace? Thanks

Added after 42 minutes:

This is, what is shown on the debugger log, when I click on the arrow-up-symbol on the QdoubleSpinbox with a breakpoint set in on_valueChanged(double) slot:


Breakpoint 1 hit
eax=0031c370 ebx=00000000 ecx=0031fbc0 edx=0031c4d4 esi=00000401 edi=0031dbd4
eip=009b1418 esp=0031c344 ebp=0031c37c iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
> 20: int temp=0;
testslider!MainWindow::on_doubleSpinBox_valueChang ed+0x28:
20 009b1418 c745f000000000 mov dword ptr [ebp-10h],0 ss:0023:0031c36c=0031c378

*** WARNING: Unable to verify checksum for C:\Qt\Qt5.0.1\5.0.1\msvc2010\lib\Qt5Cored.dll
*** WARNING: Unable to verify checksum for C:\Qt\Qt5.0.1\5.0.1\msvc2010\lib\Qt5Widgetsd.dll
*** WARNING: Unable to verify checksum for C:\Qt\Qt5.0.1\5.0.1\msvc2010\lib\Qt5Guid.dll
*** WARNING: Unable to verify checksum for C:\Qt\Qt5.0.1\5.0.1\msvc2010\plugins\platforms\qwi ndowsd.dll
sAn Haltepunkt 1 (1) im Thread 0 angehalten.
dNOTE: INFERIOR SPONTANEOUS STOP
sAngehalten.
dState changed from InferiorRunOk(11) to InferiorStopOk(14) [master]
<!qtcreatorcdbext.locals -t 2 -D -e inspect,local,return,watch -v -c -W 0
DEBUG: Discarding watchers
DEBUG: expandEntrySet local


/////////THEN I PRESSED F5


dNOTE: INFERIOR RUN REQUESTED
sAusführung angefordert...
dState changed from InferiorStopOk(14) to InferiorRunRequested(10) [master]
<g
dNOTE: INFERIOR RUN OK
sLäuft.
dState changed from InferiorRunRequested(10) to InferiorRunOk(11) [master]
Breakpoint 1 hit
eax=0031cf44 ebx=00000000 ecx=0031fbc0 edx=0031d0a8 esi=00000113 edi=0031dbd4
eip=009b1418 esp=0031cf18 ebp=0031cf50 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
> 20: int temp=0;
testslider!MainWindow::on_doubleSpinBox_valueChang ed+0x28:
20 009b1418 c745f000000000 mov dword ptr [ebp-10h],0 ss:0023:0031cf40=0031cf4c
sAn Haltepunkt 1 (1) im Thread 0 angehalten.
dNOTE: INFERIOR SPONTANEOUS STOP
sAngehalten.
dState changed from InferiorRunOk(11) to InferiorStopOk(14) [master]
<!qtcreatorcdbext.locals -t 3 -D -e inspect,local,return,watch -v -c -W 0
DEBUG: Discarding watchers
DEBUG: expandEntrySet local


//THEN I PRESSED F5 AGAIN


dNOTE: INFERIOR RUN REQUESTED
sAusführung angefordert...
dState changed from InferiorStopOk(14) to InferiorRunRequested(10) [master]
<g

dNOTE: INFERIOR RUN OK
sLäuft.
dState changed from InferiorRunRequested(10) to InferiorRunOk(11) [master]


So, is it that, what you requested? I hope so. Thanks again.

wysota
15th March 2013, 17:07
WIthout a backtrace (also called stacktrace) there is nothing I can do for you.

Marco W.
17th March 2013, 11:54
Please, could you give a link / tutorial / some advice how to do a backtrace? Thanks

rivimey
17th March 2013, 17:35
Marco, wysota is talking about the window that in VS2010 is called Call Stack. He is asking where the two calls to valueChanged are being made from.

Have you, in VS2010, enabled the MS symbol import (Options/Debug/Symbols) - it will give the debugger a lot more info and make the Call stack more useful even for Debug configuration.

The first thing I would do is verify that - without a breakpoint involved - a call to OutputDebugString("stuff") within your on_doubleSpinBox_valueChanged() function results in two lines being printed in the debugger Output window. If that happens, then I would strongly suggest you take wysota's hint and triple-check that you haven't managed to connect the signal and slot together twice. That is by far the most likely explanation for seeing.

If you don't get two lines in the Output window, the call is not happening twice... something else is happening.

Marco W.
18th March 2013, 08:05
Yes, but I am using QT Creator, so my question was, how to get this in QT Creator =/

Is the following the content, that you asked for? It is shown right after the breakpoint in the on_dblSpinBoxThresh2_valueChanged is hit the first time.



0 cPMCannyWidget::on_dblSpinBoxThresh2_valueChanged cpmcannywidget.cpp 186 0x111441a
1 cPMCannyWidget::qt_static_metacall moc_cpmcannywidget.cpp 120 0x1118a12
2 cPMCannyWidget::qt_metacall moc_cpmcannywidget.cpp 165 0x1118bdb
3 QMetaObject::metacall qmetaobject.cpp 308 0x66ad2230
4 QMetaObject::activate qobject.cpp 3456 0x66b1628f
5 QMetaObject::activate qobject.cpp 3316 0x66b15c11
6 QDoubleSpinBox::valueChanged moc_qspinbox.cpp 411 0x64e167ab
7 QDoubleSpinBoxPrivate::emitSignals qspinbox.cpp 1074 0x64b8f722
8 QAbstractSpinBoxPrivate::setValue qabstractspinbox.cpp 1678 0x64ad079d
9 QAbstractSpinBox::stepBy qabstractspinbox.cpp 617 0x64acd702
10 QAbstractSpinBoxPrivate::updateState qabstractspinbox.cpp 1571 0x64ad0232
11 QAbstractSpinBox::mousePressEvent qabstractspinbox.cpp 1283 0x64acf363
12 QWidget::event qwidget.cpp 7831 0x649ca039
13 QAbstractSpinBox::event qabstractspinbox.cpp 752 0x64acdb30
14 QApplicationPrivate::notify_helper qapplication.cpp 3394 0x649828ce
15 QApplication::notify qapplication.cpp 2958 0x6498093c
16 QCoreApplication::notifyInternal qcoreapplication.cpp 767 0x66ac74c4
17 QCoreApplication::sendSpontaneousEvent qcoreapplication.h 206 0x66bd7198
18 QApplicationPrivate::sendMouseEvent qapplication.cpp 2465 0x6497fa65
19 QWidgetWindow::handleMouseEvent qwidgetwindow.cpp 387 0x649fdbc0
20 QWidgetWindow::event qwidgetwindow.cpp 139 0x649fd134
21 QApplicationPrivate::notify_helper qapplication.cpp 3394 0x649828ce
22 QApplication::notify qapplication.cpp 2825 0x6498030a
23 QCoreApplication::notifyInternal qcoreapplication.cpp 767 0x66ac74c4
24 QCoreApplication::sendSpontaneousEvent qcoreapplication.h 206 0x66bd7198
25 QGuiApplicationPrivate::processMouseEvent qguiapplication.cpp 1425 0x7efe64
26 QGuiApplicationPrivate::processWindowSystemEvent qguiapplication.cpp 1257 0x7ef6d2
27 QWindowSystemInterface::sendWindowSystemEventsImpl ementation qwindowsysteminterface.cpp 536 0x7d8541
28 QWindowSystemInterface::sendWindowSystemEvents qwindowsysteminterface.cpp 516 0x7d84c9
29 QWindowsGuiEventDispatcher::sendPostedEvents qwindowsguieventdispatcher.cpp 86 0xf69aff4
30 qt_internal_proc qeventdispatcher_win.cpp 423 0x66b4fb07
31 InternalCallWinProc USER32 0x76bec4e7
32 UserCallWinProcCheckWow USER32 0x76bec5e7
33 DispatchMessageWorker USER32 0x76becc19
34 DispatchMessageW USER32 0x76becc70
35 QEventDispatcherWin32::processEvents qeventdispatcher_win.cpp 744 0x66b50bf3
36 QWindowsGuiEventDispatcher::processEvents qwindowsguieventdispatcher.cpp 78 0xf69af5e
37 QEventLoop::processEvents qeventloop.cpp 137 0x66ac40c1
38 QEventLoop::exec qeventloop.cpp 212 0x66ac421e
39 QCoreApplication::exec qcoreapplication.cpp 1020 0x66ac79fd
40 QGuiApplication::exec qguiapplication.cpp 1192 0x7ef468
41 QApplication::exec qapplication.cpp 2670 0x6497ffb9
42 main main.cpp 13 0x110242e
43 WinMain qtmain_win.cpp 131 0x111a8ea
44 __tmainCRTStartup crtexe.c 547 0x1119e10
45 WinMainCRTStartup crtexe.c 371 0x1119b9f
46 BaseThreadInitThunk kernel32 0x7701ed6c
47 __RtlUserThreadStart ntdll 0x7727377b
48 _RtlUserThreadStart ntdll 0x7727374e




On the second time, the breakpoint is hit:





0 cPMCannyWidget::on_dblSpinBoxThresh2_valueChanged cpmcannywidget.cpp 186 0x111441a
1 cPMCannyWidget::qt_static_metacall moc_cpmcannywidget.cpp 120 0x1118a12
2 cPMCannyWidget::qt_metacall moc_cpmcannywidget.cpp 165 0x1118bdb
3 QMetaObject::metacall qmetaobject.cpp 308 0x66ad2230
4 QMetaObject::activate qobject.cpp 3456 0x66b1628f
5 QMetaObject::activate qobject.cpp 3316 0x66b15c11
6 QDoubleSpinBox::valueChanged moc_qspinbox.cpp 411 0x64e167ab
7 QDoubleSpinBoxPrivate::emitSignals qspinbox.cpp 1074 0x64b8f722
8 QAbstractSpinBoxPrivate::setValue qabstractspinbox.cpp 1678 0x64ad079d
9 QAbstractSpinBox::stepBy qabstractspinbox.cpp 617 0x64acd702
10 QAbstractSpinBox::timerEvent qabstractspinbox.cpp 1182 0x64acee20
11 QObject::event qobject.cpp 1052 0x66b10ab3
12 QWidget::event qwidget.cpp 8235 0x649cae59
13 QAbstractSpinBox::event qabstractspinbox.cpp 752 0x64acdb30
14 QApplicationPrivate::notify_helper qapplication.cpp 3394 0x649828ce
15 QApplication::notify qapplication.cpp 3359 0x64982450
16 QCoreApplication::notifyInternal qcoreapplication.cpp 767 0x66ac74c4
17 QCoreApplication::sendEvent qcoreapplication.h 203 0x66acc849
18 QEventDispatcherWin32Private::sendTimerEvent qeventdispatcher_win.cpp 572 0x66b4ffd8
19 qt_internal_proc qeventdispatcher_win.cpp 427 0x66b4fb5a
20 InternalCallWinProc USER32 0x76bec4e7
21 UserCallWinProcCheckWow USER32 0x76bec5e7
22 DispatchMessageWorker USER32 0x76becc19
23 DispatchMessageW USER32 0x76becc70
24 QEventDispatcherWin32::processEvents qeventdispatcher_win.cpp 744 0x66b50bf3
25 QWindowsGuiEventDispatcher::processEvents qwindowsguieventdispatcher.cpp 78 0xf69af5e
26 QEventLoop::processEvents qeventloop.cpp 137 0x66ac40c1
27 QEventLoop::exec qeventloop.cpp 212 0x66ac421e
28 QCoreApplication::exec qcoreapplication.cpp 1020 0x66ac79fd
29 QGuiApplication::exec qguiapplication.cpp 1192 0x7ef468
30 QApplication::exec qapplication.cpp 2670 0x6497ffb9
31 main main.cpp 13 0x110242e
32 WinMain qtmain_win.cpp 131 0x111a8ea
33 __tmainCRTStartup crtexe.c 547 0x1119e10
34 WinMainCRTStartup crtexe.c 371 0x1119b9f
35 BaseThreadInitThunk kernel32 0x7701ed6c
36 __RtlUserThreadStart ntdll 0x7727377b
37 _RtlUserThreadStart ntdll 0x7727374e




Thanks

wysota
18th March 2013, 18:51
As you can see in your second trace, there is just a single call to your slot method. The slot is not calling itself. It could be that the slot is called, then it returns and is called again but it doesn't happen as a result of the breakpoint. There is a timer event here so maybe it fires twice because stopping in the breakpoint and not continuing fast enough causes the timer to fire again. That's perfectly understandable.

Marco W.
19th March 2013, 08:35
Ok, thanks wysota!

The explanation concerning the timer is understandable. However, I wonder why the timer triggers only once again, and not several times: if I wait for several seconds before continuing the second break, the slot is not called again.

Is there a documentation for this, or in general, how the processing of a click on the up/down-arrow-button of a QdoubleSpinBox is done?

wysota
19th March 2013, 12:48
However, I wonder why the timer triggers only once again, and not several times
This is easy to explain. Timers fire as a result of event processing. When the timer fires for the first time, you block the event loop with the breakpoint. When you continue the flow returns to the event loop and the timer gets fired again. It's not that if you wait for 100 seconds and the timeout for the timer is 10 seconds, you should get 10 timeouts. You will get just one.

Marco W.
19th March 2013, 13:39
Ok, thanks, but I still do not understand why a timer is fired as a result of event processing and why a timer is started by clicking on the up-arrow of the QdoubleSpinBox.

After all, the result, that having a breakpoint set leads to a different behaviour than having no breakpoint set, is still strange to me.

wysota
19th March 2013, 16:27
Ok, thanks, but I still do not understand why a timer is fired as a result of event processing
That's how it works and you have to live with it.


and why a timer is started by clicking on the up-arrow of the QdoubleSpinBox.
A timer is started as a result of pressing the arrow so that Qt can keep incrementing the value while you're keeping the arrow pressed.


After all, the result, that having a breakpoint set leads to a different behaviour than having no breakpoint set, is still strange to me.
Again, you have to live with it.