如何防止 Qt 中的 currentCellChanged 信号或跳过 "processing"?
How to prevent currentCellChanged signal in Qt or skip "processing"?
我有一个菜单项和一个带插槽的 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
}
}
但是,当我单击 "open" 时,"processing" 部分仍然会在打开完成后运行。有没有更可靠的方法暂时禁用 checkFooChanged "processing" 直到打开完全完成?注意:当控制 returns 给用户时,我需要将标志设置回 true,以便在用户更改 fooTableWidget.
上的行时调用 "processing"
更新
这是一个最小的例子以及 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);
}
所以问题似乎是主要window重获焦点引起的。
在你的情况下,我看到你想暂时禁用 currentCellChanged
信号触发器,为此你必须使用 blockSignals()
:
void MainWindow::open()
{
ui->fooTableWidget->blockSignals(true);
ui->fooTableWidget->insertRow(0);
ui->fooTableWidget->insertRow(1);
ui->fooTableWidget->blockSignals(false);
}
更新:
正如您所指出的,问题似乎是由焦点变化引起的,当您打开对话框时,焦点被消除,而当焦点关闭时,它 returns 到 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);
}
我有一个菜单项和一个带插槽的 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
}
}
但是,当我单击 "open" 时,"processing" 部分仍然会在打开完成后运行。有没有更可靠的方法暂时禁用 checkFooChanged "processing" 直到打开完全完成?注意:当控制 returns 给用户时,我需要将标志设置回 true,以便在用户更改 fooTableWidget.
上的行时调用 "processing"更新
这是一个最小的例子以及 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);
}
所以问题似乎是主要window重获焦点引起的。
在你的情况下,我看到你想暂时禁用 currentCellChanged
信号触发器,为此你必须使用 blockSignals()
:
void MainWindow::open()
{
ui->fooTableWidget->blockSignals(true);
ui->fooTableWidget->insertRow(0);
ui->fooTableWidget->insertRow(1);
ui->fooTableWidget->blockSignals(false);
}
更新:
正如您所指出的,问题似乎是由焦点变化引起的,当您打开对话框时,焦点被消除,而当焦点关闭时,它 returns 到 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);
}