QItemSelectionModel currentChange 信号在应用程序启动时发出?

and*_*ari 1 qt qlistview qmainwindow qt5

所以我有一个 QMainWindow 并在其构造函数中执行以下操作:

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
});
Run Code Online (Sandbox Code Playgroud)

为什么在应用程序启动时会发出 currentChanged 以及如何避免在实际单击 ListView 之前发出 currentChanged?

Tay*_*510 5

[怎么了?]

由于listView是您的 中唯一的小部件QMainWindow,因此它会在应用程序启动时自动聚焦。一旦listView获得焦点,如果还没有当前项目,第一个项目将自动成为当前项目。因此发出了信号。

[解决方案]

选项1

将其他小部件添加到您的应用程序中,并调用QWidget::setFocus其中一个小部件,使其成为应用程序启动时默认的焦点小部件。

选项2

调用QListView::setFocusPolicy并 make it Qt::ClickFocus,因此仅当单击其中一项时 listView 才会获得焦点。

选项3

该信号QItemSelectionModel::currentChanged实际上有两个参数:QModelIndex &currentQModelIndex &privious。通过传统的信号/槽连接来使用它们。例如

connect(ui->listView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(yourSlot(QModelIndex, QModelIndex)));
Run Code Online (Sandbox Code Playgroud)

在插槽中:

void MainWindow::yourSlot(QModelIndex cur, QModelIndex pre)
{
    if(pre.isValid()) {
        // do stuff
    }        
}
Run Code Online (Sandbox Code Playgroud)

PSpre无效表示之前没有当前项目。这会绕过 listView 第一次聚焦时自动选择发出的信号。