PDA

View Full Version : Can QListWidget's clear() be called from a slot connected with one of its signal?



iunknwn
30th September 2015, 17:21
Consider this code


class SomeClass : public QWidget
{
public:
SomeClass();
...
private:
QListWidget* _listWgt;
};

SomeClass::SomeClass(QWidget* parent) : QWidget(parent)
{
_listWgt = new QListWidget(this);
connect(_listWgt, SIGNAL(itemDoubleClicked(QListWidgetItem*), this, SLOT(onItemDoubleClicked(QListWidgetItem*));
}

void SomeClass::onItemDoubleClicked(QListWidgetItem* item)
{
QString itemText = item->text();
if(_listWgt){
_listWgt->clear();
}
// Code to repopulate _listWgt with new list of items base on 'itemText'
// follows.

}

My code is crashing in Qt as some timer event occurs on _listWgt that perhaps has information of _listWgt before it entered onItemDoubleClicked() slot, but after this slot is done, _listWgt doesn't reflect that state.

I'm suspecting clear() as technically, it will try to delete the item on which the doubleClicked signal happened.

Can anyone agree or confirm my suspicion?

Thanks.

yeye_olive
1st October 2015, 08:31
The cause of the crash could be anywhere in your program. Have you tried this suspicious pattern (calling clear() from a slot connected to itemDoubleClicked) in a minimal example?

You could also try to turn the connection into a queued one and see if this changes anything:

connect(_listWgt, SIGNAL(itemDoubleClicked(QListWidgetItem*), this, SLOT(onItemDoubleClicked(QListWidgetItem*), Qt::QueuedConnection);
That way, the slot is only invoked after control has returned to the event loop.

anda_skoa
1st October 2015, 08:40
Well, what does the backtrace of your crash say?
Does it still crash if you remove the call to clear()?

Cheers,
_

iunknwn
1st October 2015, 19:56
Thanks for your response guys!

The traceback in debugger was not very helpful. The real application is 20+ million lines of code, but I just extracted conceptual code. Didn't really try to create a small test program, but the issue has been resolved.

There was a 100 ms timer that would scroll the list of items to the far right automatically after the new list of items were populated. Randomly, this feature would cause the crash. See callstack below.



STACK ? 6 ? 0x64f55329 QListView::updateGeometries
STACK ? 7 ? 0x64f4d3d7 QListView::indexAt
STACK ? 8 ? 0x64f32568 QAbstractItemView::horizontalScrollbarValueChanged
STACK ? 9 ? 0x6a5a7110 QMetaObject::activate
STACK ? 10 ? 0x6504ab10 QAbstractSlider::valueChanged
STACK ? 11 ? 0x64e0fdb9 QAbstractSlider::setValue
STACK ? 12 ? 0x64e0fb42 QAbstractSlider::setRange
STACK ? 13 ? 0x64f54c74 QListView::updateGeometries
STACK ? 14 ? 0x64f303a1 QAbstractItemView::doItemsLayout
STACK ? 15 ? 0x64f4a2b9 QListView::doItemsLayout
STACK ? 16 ? 0x64f396ee QAbstractItemView::timerEvent
STACK ? 17 ? 0x6a5aa5ec QObject::event
STACK ? 18 ? 0x64b2e913 QWidget::event
STACK ? 19 ? 0x64e4ac97 QFrame::event
STACK ? 20 ? 0x64eba1a4 QAbstractScrollArea::event
STACK ? 21 ? 0x64af1a36 QApplicationPrivate::notify_helper


Well, just by changing the horizontal scrollbar policy to always visible instead of automatic on the QListWidget solved this issue!

This is on Qt 4.8.2 on Windows x64 MSVS 2012