代码之家  ›  专栏  ›  技术社区  ›  gornvix

如何防止currentCellChanged信号在qt或跳过“处理”?

  •  2
  • gornvix  · 技术社区  · 6 年前

    我有一个菜单项和一个带有插槽的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“处理”,直到完全打开为止?注意:当控件返回给用户时,需要将flag设置回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 回复  |  直到 6 年前
        1
  •  1
  •   eyllanesc RAHUL KUMAR    6 年前

    在你的情况下,我看到你想禁用 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);
    }