Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Unsolved calling QListWidgetItem setText() or setCheckState() on crashes Qt application

    General and Desktop
    qt5 qt5.13.1 qlistwidget qlistwidgetitem
    2
    3
    537
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • CybeX
      CybeX last edited by

      I have an application which needs to populate a QListWidget with entries. The list widget should have 2 data entries:

      1. Name
      2. 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() line

      1  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() line

      idx	@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 this q 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>
      
      1 Reply Last reply Reply Quote 0
      • VRonin
        VRonin last edited by

        I suspect the problem is to something connecting to that signal.

        Try not passing ui->listDriveInfo to the item constructor (this prevents the signal being sent when you change the data)

        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
        ~Napoleon Bonaparte

        On a crusade to banish setIndexWidget() from the holy land of Qt

        1 Reply Last reply Reply Quote 0
        • CybeX
          CybeX last edited by CybeX

          @VRonin

          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?

          1 Reply Last reply Reply Quote 0
          • First post
            Last post