Как предотвратить сигнал currentCellChanged в Qt или пропустить «обработку»? - PullRequest
0 голосов
/ 08 июня 2018

У меня есть пункт меню и QTableWidget со слотами:

connect(ui->actionOpen, &QAction::triggered, this, &MainWindow::open);
connect(ui->fooTableWidget, SIGNAL(currentCellChanged(int, int, int, int)), 
    this, SLOT(checkFooChanged(int, int, int, int)));

При открытии файла я пытаюсь предотвратить что-либо в слоте, используя переменную флага:

void MainWindow::open()
{
    flag = false;
    ui->fooTableWidget->insertRow(0);
    ui->fooTableWidget->insertRow(1);
    flag = true;
}

void MainWindow::checkFooChanged(int row, int, int previousRow, int)
{
    if (flag && row != previousRow)
    {
        qDebug() << "processing";
        // do something here 
    }
}

Однако, когда я нажимаю «открыть», раздел «обработка» запускается в любом случае, после того, как открытие заканчиваетсяЕсть ли более надежный способ временно отключить «обработку» checkFooChanged до полного завершения открытия?Примечание. Мне нужно, чтобы флаг возвращался к значению true, когда элемент управления возвращается пользователю, чтобы была вызвана «обработка», если пользователь изменяет строку в fooTableWidget.

Обновление

Вот минимальный пример вместе с предложениями eyllanesc:

#include <QDebug>
#include <QTableWidget>
#include <QFileDialog>
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->fooTableWidget->setColumnCount(1);
    connect(ui->actionOpen, &QAction::triggered, this, &MainWindow::open);
    connect(ui->fooTableWidget, SIGNAL(currentCellChanged(int, int, int, int)),
        this, SLOT(checkFooChanged(int, int, int, int)));
}

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

void MainWindow::checkFooChanged(int row, int, int previousRow, int)
{
    qDebug() << "processing: " << row << ' ' << previousRow;
}

void MainWindow::open()
{
    QString fileName;
    fileName = QFileDialog::getOpenFileName(this, tr("Open"), "", "(*.emx)");
    if (fileName.isEmpty())
        return;
    qDebug() << "file " << fileName;
    ui->fooTableWidget->blockSignals(true);
    ui->fooTableWidget->setRowCount(0);
    ui->fooTableWidget->insertRow(0);
    QTableWidgetItem *item;
    item = new QTableWidgetItem();
    ui->fooTableWidget->setItem(0, 0, item);
    item->setText("Oh hi there!");
    ui->fooTableWidget->blockSignals(false);
}

Таким образом, проблема, кажется, вызвана восстановлением фокуса главного окна.

1 Ответ

0 голосов
/ 08 июня 2018

В вашем случае я вижу, что вы хотите временно отключить триггер сигнала currentCellChanged, для этого вы должны использовать blockSignals():

void MainWindow::open()
{
    ui->fooTableWidget->blockSignals(true);
    ui->fooTableWidget->insertRow(0);
    ui->fooTableWidget->insertRow(1);
    ui->fooTableWidget->blockSignals(false);
}

Обновление:

Как вы указываете, кажется, что проблема вызвана сменой фокуса, когда вы открываете диалоговое окно, фокус устраняется, а когда фокус закрывается, он возвращается к centralWidget, генерируя этот неожиданный эффект,Возможное решение - установить фокус в MainWindow.

void MainWindow::open()
{
    QString fileName;
    fileName = QFileDialog::getOpenFileName(this, tr("Open"), "", "(*.emx)");
    if (fileName.isEmpty())
        return;

    setFocus(); //<--

    ui->fooTableWidget->blockSignals(true);
    ui->fooTableWidget->setRowCount(0);
    ui->fooTableWidget->insertRow(0);
    QTableWidgetItem *item = new QTableWidgetItem();
    ui->fooTableWidget->setItem(0, 0, item);
    item->setText("Oh hi there!");
    ui->fooTableWidget->blockSignals(false);
}
...