andreihondrari
andreihondrari

Reputation: 5833

QItemSelectionModel currentChange signal is emitted on application start?

So I have a QMainWindow and in its constructor I do the following stuff:

QStringList stringList;
stringList << "aaa" << "bbb" << "ccc";
QStringListModel *list = new QStringListModel(stringList);
ui->listView->setModel(list);

stringList.append("ddd");
list->setStringList(stringList);

QObject::connect(ui->listView->selectionModel(), &QItemSelectionModel::currentChanged, [&]() {
    //do stuff
});

Why is the currentchanged emitted when the application starts and how can I avoid emitting the currentChanged until I actually click on the ListView?

Upvotes: 1

Views: 1660

Answers (1)

Tay2510
Tay2510

Reputation: 5978

[What's wrong?]

Since the listView is the only widget in your QMainWindow, it will be automatically focused as the application starts. Once the listView gets focused, the first item automatically becomes the current item if there wasn't already a current item. Hence the signal emitted.

[Solution]

Option 1

Add other widgets into your application and call QWidget::setFocus on one of them to make it the default focused widget as app starts.

Option 2

Call QListView::setFocusPolicy and make it Qt::ClickFocus, so the listView will only be focused if one of the items is clicked.

Option 3

The signal QItemSelectionModel::currentChanged has actually two arguments: QModelIndex &current and QModelIndex &privious. Use them by conventional signal/slot connection. For example

connect(ui->listView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(yourSlot(QModelIndex, QModelIndex)));

In the slots :

void MainWindow::yourSlot(QModelIndex cur, QModelIndex pre)
{
    if(pre.isValid()) {
        // do stuff
    }        
}

P.S. pre being invalid signifies that there was no current item previously. This bypasses the signal emit by auto-selected for the first time the listView is focused.

Upvotes: 5

Related Questions