calling QListWidgetItem setText() or setCheckState() on crashes Qt application
-
I have an application which needs to populate a QListWidget with entries. The list widget should have 2 data entries:
- Name
- Checkbox
Using this as some reference and adapting it to something similar to this to enable user altering the QListWidgetItem::setCheckedState(), I get the following:
MainWindow constructor
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); //... // Called AFTER ui is setup // Call stack for the method below is: initGui > connectSettings > connectDriveListChanges > updateDrivesList updateDrivesListWidget(); //... }
later in constructor, this is called:
void MainWindow::updateDrivesListWidget() { //... // Get name of item QString name = QString("Local Disk (%1)").arg(s); bool enabled = attachedDriveList.value(s); // create item for QListWidget named listDriveInfo on form // QListWidgetItem* item = new QListWidgetItem(name, ui->listDriveInfo); <---crashes when setting text QListWidgetItem* item = new QListWidgetItem(ui->listDriveInfo); //set checkable and state item->setText(name); < -----tried as alternative to crash above item->setCheckState(enabled ? Qt::Checked : Qt::Unchecked); Qt::ItemFlags localFlags = item->flags(); localFlags = localFlags | Qt::ItemIsUserCheckable; item->setFlags(localFlags); // add item to list ui->listDriveInfo->addItem(item); //... }
I have run also ran Run qmake, also cleaned and rebuilt the project (incase of some invalid reference to the listWidget) but it keeps crashing at this same spot.
Stepping through
item->setText(name);
callstack, I see the application crashes at this point:qlistwidget.cpp (ref)
void QListModel::itemChanged(QListWidgetItem *item, const QVector<int> &roles) { const QModelIndex idx = index(item); emit dataChanged(idx, idx, roles); <-------crash when emitting signal }
Call stack here at the
emit dataChange()
line1 QListModel::itemChanged qlistwidget.cpp 455 0x172b4ee8 2 QListWidgetItem::setData qlistwidget.cpp 745 0x172b5c28 3 QListWidgetItem::setText qlistwidget.h 179 0x4b2a7e 4 MainWindow::updateDrivesListWidget MainWindow.cpp 1074 0x44d953 5 MainWindow::updateDrivesList MainWindow.cpp 1390 0x45015b 6 MainWindow::connectDriveListChanges MainWindow.cpp 933 0x44c83d 7 MainWindow::connectSettings MainWindow.cpp 466 0x448161 8 MainWindow::initGui MainWindow.cpp 57 0x444b4c 9 MainWindow::MainWindow MainWindow.cpp 17 0x44449f 10 qMain main.cpp 230 0x466faf 11 WinMain *16 qtmain_win.cpp 97 0x48df70 12 main 0x4e0bfd
Debugger Content at the
emit dataChange()
lineidx @0x56af450 QModelIndex c 0 int i 783195744 quintptr m @0x2e9a2b18 QListModel r 0 int item @0x2eae9e60 QListWidgetItem [vptr] _vptr.QListWidgetItem d @0x2eb36c80 QListWidgetItemPrivate dummy <0 items> QVector<void*> itemFlags (Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled) (0x0035) Qt::ItemFlags rtti 0 int view "listDriveInfo" QListWidget roles <2 items> QVector<int> & 0 int 2 int this @0x2e9a2b18 QListModel [QAbstractListModel] @0x2e9a2b18 QAbstractListModel [d] @0x2e9a32f0 QAbstractItemModelPrivate [parent] "listDriveInfo" QListWidget [children] <0 items> [properties] <at least 0 items> [methods] <0 items> [extra] cachedIndexes <0 items> QModelIndexList items <1 items> QList<QListWidgetItem*> staticMetaObject @0x17425334 QMetaObject
Any idea why it may crash at this point?
Update (not a solution), an extension only
from the signal emitted
emit dataChanged(idx, idx, roles);
in the function (mentioned above)QListModel::itemChanged()
, it reaches this line (shown below) via this signal-slot connection, but I have absolutely no idea how to trace it further, nor what ever thisq
refers to.void QListWidgetPrivate::_q_emitItemChanged(const QModelIndex &index) { Q_Q(QListWidget); emit q->itemChanged(listModel()->at(index.row())); }
q
is shown here to connect the signals & slots.Stack Trace here
1 QListWidgetPrivate::_q_emitItemChanged qlistwidget.cpp 1198 0x171948ac 2 QListWidget::qt_static_metacall moc_qlistwidget.cpp 196 0x17198264 3 QMetaObject::activate qobject.cpp 3809 0x6bb282a7 4 QMetaObject::activate qobject.cpp 3660 0x6bb2851b 5 QAbstractItemModel::dataChanged moc_qabstractitemmodel.cpp 557 0x6bac9e3f 6 QListModel::itemChanged qlistwidget.cpp 455 0x17194eff 7 QListWidgetItem::setData qlistwidget.cpp 745 0x17195c28 8 QListWidgetItem::setText qlistwidget.h 179 0x4b2a7e 9 MainWindow::updateDrivesListWidget MainWindow.cpp 1074 0x44d953 10 MainWindow::updateDrivesList MainWindow.cpp 1390 0x45015b 11 MainWindow::connectDriveListChanges MainWindow.cpp 933 0x44c83d 12 MainWindow::connectSettings MainWindow.cpp 466 0x448161 13 MainWindow::initGui MainWindow.cpp 57 0x444b4c 14 MainWindow::MainWindow MainWindow.cpp 17 0x44449f 15 qMain main.cpp 230 0x466faf 16 WinMain *16 qtmain_win.cpp 97 0x48df70 17 main 0x4e0bfd
Debugger Output here:
Locals index @0x56af450 QModelIndex & c 0 int i 783486936 quintptr m @0x2e9e3280 QListModel [QAbstractListModel] @0x2e9e3280 QAbstractListModel [d] @0x2e9e3a58 QAbstractItemModelPrivate [parent] "listDriveInfo" QListWidget [children] <0 items> [properties] <at least 0 items> [methods] <0 items> [extra] cachedIndexes <0 items> QModelIndexList items <1 items> QList<QListWidgetItem*> staticMetaObject @0x17305334 QMetaObject r 0 int Inspector Expressions Return Value Tooltip q <not accessible>
-
Doing a few (rather simple) tests, I found the following (which confirms your suspicion)
Works: (but no check box) - this is expected to work
// create item QListWidgetItem* item = new QListWidgetItem(name, ui->listDriveInfo); // item->setText(name); // item->setFlags(item->flags() | Qt::ItemIsUserCheckable); // item->setCheckState(enabled ? Qt::Checked : Qt::Unchecked); // add item to list ui->listDriveInfo->addItem(item);
this crashes on
setFlags()
call// create item QListWidgetItem* item = new QListWidgetItem(name, ui->listDriveInfo); // item->setText(name); //set checkable and state Qt::ItemFlags localFlags = item->flags(); item->setFlags(localFlags | Qt::ItemIsUserCheckable); item->setCheckState(enabled ? Qt::Checked : Qt::Unchecked); // add item to list ui->listDriveInfo->addItem(item);
but these 2 both work (without setting owning QListWidget)
// create item QListWidgetItem* item = new QListWidgetItem(name); // item->setText(name); //set checkable and state Qt::ItemFlags localFlags = item->flags(); item->setFlags(localFlags | Qt::ItemIsUserCheckable); item->setCheckState(enabled ? Qt::Checked : Qt::Unchecked); // add item to list ui->listDriveInfo->addItem(item);
and
// create item QListWidgetItem* item = new QListWidgetItem(); // item->setText(name); //set checkable and state Qt::ItemFlags localFlags = item->flags(); item->setFlags(localFlags | Qt::ItemIsUserCheckable); item->setCheckState(enabled ? Qt::Checked : Qt::Unchecked); // add item to list ui->listDriveInfo->addItem(item);
Testing:
I create a new application, did exactly the same (add a string and a checkbox) and that work 100%. Create a form, throw on a
QListWidget
and run it with this code.QListWidgetItem* item = new QListWidgetItem("New", ui->listWidget); item->setFlags(item->flags() | Qt::ItemIsUserCheckable); item->setCheckState(Qt::Unchecked); QListWidgetItem* item1 = new QListWidgetItem("New 1", ui->listWidget); item1->setFlags(item->flags() | Qt::ItemIsUserCheckable); item1->setCheckState(Qt::Unchecked); QListWidgetItem* item2 = new QListWidgetItem("New 2", ui->listWidget); item2->setFlags(item->flags() | Qt::ItemIsUserCheckable); item2->setCheckState(Qt::Unchecked); ui->listWidget->addItem(item); ui->listWidget->addItem(item1); ui->listWidget->addItem(item2); connect(ui->listWidget, &QListWidget::itemClicked, this, [this](QListWidgetItem * i) { // Get drive info from driveList int pos = ui->listWidget->row(i); // check state & set state bool active = i->checkState() == Qt::Checked; qDebug() << (active ? "enabled" : "disabled"); });
So my question is, bug (on whose side) or some setting on my side? Thoughts on what to look for?