QListWidget::itemSelectionChanged() запускается дважды с клавиатурой

Я использую QListWidget для выбора файлов в списке, при выборе я читаю этот файл, в случае ошибки я очищаю все выборы и всплываю ошибка.

Все работает нормально, используя только мышь, но при использовании стрелок клавиатуры на плохом файле сигнал срабатывает дважды.

Это раздражает, так как ошибка появляется дважды.

Есть ли способ вывести ошибку только один раз в этом случае?

Код для воспроизведения поведения:

MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMessageBox>
#include <QMainWindow>
#include <QListWidget>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:

    MainWindow(QWidget *parent = 0)
        : QMainWindow(parent)
    {
        // Window title
        setWindowTitle("My Widget");
        setMinimumSize(400,500);

        // Creation of the QListWidgets
        _listWidget = new QListWidget;

        // Selection mode
        _listWidget->setSelectionMode(QAbstractItemView::SingleSelection);

        // Fill the table
        for(int i = 1; i <= 10; i++)
            _listWidget->addItem(QString::number(i));

        // Connect signals and slots
        connect(_listWidget, SIGNAL(itemSelectionChanged()),
                this, SLOT(onSelect()));

        // Set central widget
        setCentralWidget(_listWidget);
    }

    ~MainWindow() {}

public slots:

    void onSelect()
    {
        QList<QListWidgetItem*> itemsList = _listWidget->selectedItems();

        foreach (QListWidgetItem* item, itemsList)
        {
            // If the item is not valid, I want to unselect it
            if(!isValid(item))
            {
                // Block signal for fire error only one
                _listWidget->blockSignals(true);
                _listWidget->clearSelection();
                _listWidget->setCurrentItem(0);
                _listWidget->blockSignals(false);
                QMessageBox::critical(0, "Error", "Item Not Valid");
            }
        }
    }

private:

    bool isValid(QListWidgetItem* item)
    {
        int number = item->text().toInt();
        return (number%3 != 0);
    }

    QListWidget *_listWidget;
};

#endif // MAINWINDOW_H

main.cpp

#include <MainWindow.h>

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    MainWindow w;
    w.show();

    return a.exec();
}

person Giacogiac    schedule 17.10.2014    source источник
comment
Я не знаю, почему сигнал испускается дважды. Воспользуйтесь отладчиком, поставьте точку останова и узнайте, откуда поступают вызовы.   -  person Silicomancer    schedule 18.10.2014
comment
Испускание происходит из Qt, мой код не запускает никаких сигналов, я не могу поставить точку останова в коде Qt.   -  person Giacogiac    schedule 20.10.2014
comment
Да, загляните в исходники Qt, используя стек вызовов, и попытайтесь выяснить, почему эти эмиссии выполняются.   -  person Silicomancer    schedule 20.10.2014
comment
Я не знаю, как это сделать, код Qt, запускающий сигнал, уже скомпилирован, и стек вызовов просто проводит меня через какой-то дизассемблированный код.   -  person Giacogiac    schedule 21.10.2014


Ответы (1)


Существует простой обходной путь для вашей проблемы с диалогом. Вместо использования QMessageBox::critical() вы можете создать диалоговое окно в куче, которое автоматически уничтожается при закрытии, сохранить его адрес в QPointer и проверить указатель перед повторным открытием диалогового окна.

person Silicomancer    schedule 18.10.2014
comment
Это было бы, если бы я хотел, чтобы мой диалог появлялся один раз за всю жизнь приложения, но он может появляться несколько раз, если пользователь продолжает выбирать плохие файлы, я просто не хочу, чтобы он появлялся дважды для одного действия. - person Giacogiac; 20.10.2014
comment
Нет. Этот обходной путь предотвращает появление диалогового окна дважды одновременно. Не дважды за время жизни приложения. Почему вы так думаете? - person Silicomancer; 20.10.2014
comment
Второй диалог появляется после закрытия первого. Он появляется не дважды одновременно, а дважды подряд. - person Giacogiac; 21.10.2014