Search code examples
c++qtqt5qtablewidget

How to prevent currentCellChanged signal in Qt or skip "processing"?


I have a menu item and a QTableWidget with slots:

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

When opening a file I attempt to prevent anything being done in the slot by using a flag variable:

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 
    }
}

However when I click on "open" the "processing" section runs anyway, after open finishes. Is there a more reliable way to temporarily disable the checkFooChanged "processing" until open has completely finished? Note: I need flag to be set back to true when control returns to the user, so that the "processing" gets called if the user changes the row on fooTableWidget.

Update

Here is a minimal example along with the suggestions of 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);
}

So the problem seems to be caused by the main window regaining focus.


Solution

  • In your case I see that you want to disable the currentCellChanged signal trigger temporarily, for this you must use blockSignals():

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

    Update:

    As you indicate it seems that the problem is caused by the change of focus, when you open the dialog the focus is eliminated and when the focus is closed it returns to the centralWidget, generating that unexpected effect, a possible solution is to establish the focus in the 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);
    }