Search code examples
c++qtqt4qlistwidget

QListWidget item at 0th index is selected by default


I have a QListWidget which has some item, and I have "Remove" button on my form which actually removes item from list. Problem is that when form load for first time and I press remove without selecting any item from list, it takes the item at 0th index by default and remove it. Following is the code segment:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ui->listWidget->addItem(new QListWidgetItem("Item1"));
    ui->listWidget->addItem(new QListWidgetItem("Item2"));
    ui->listWidget->addItem(new QListWidgetItem("Item3"));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_btnRemove_clicked()
{
    printf("on_btnRemove_clicked() \n");

    int currentRow = ui->listWidget->currentRow();
    QModelIndex currentIndex = ui->listWidget->currentIndex();
    QListWidgetItem* currentItem = ui->listWidget->currentItem();

    printf("currentRow: %d\n", currentRow);

    if(currentRow > -1) {
        printf("currentIndex.data() %s: \n", currentIndex.data().toString().toStdString().c_str());
        printf("currentItem->data(0): %s \n", currentItem->data(0).toString().toStdString().c_str());

        QListWidgetItem* itemToDelete = ui->listWidget->takeItem(currentRow);
        delete itemToDelete;
        itemToDelete = NULL;
    }
}

Any idea how to override this behavior or at least anyway that I can show that 0th index is selected with default blue background of item.


Solution

  • You can show the selected item after adding the items, by calling setCurrentItem:-

    QListWidgetItem* pSelectedItem = new QListWidgetItem("Item1");
    
    ui->listWidget->addItem(pSelectedItem);
    ui->listWidget->addItem(new QListWidgetItem("Item2"));
    ui->listWidget->addItem(new QListWidgetItem("Item3"));
    
    ui->listWidget->setCurrentItem(pSelectedItem);
    

    As the docs state: -

    Unless the selection mode is NoSelection, the item is also be selected.

    Alternatively, rather than retrieving the current Item, get the selected items with selectedItems(), which I would expect to return an empty list with which you can check the number of items: -

     if(ui->listWidget->selectedItems().count())
     {
         // delete items
     }
    

    Note that a call to clearSelection states:-

    Deselects all selected items. The current index will not be changed.

    I would expect this means that requesting the current index or current item can return a valid index or item, which is why delete removes the item, even though it is not selected.