我正在寻找一种干净的方法来响应QTableWidgetItem更改其文本的事件。我尝试使用Signal QTableWidget::itemChanged(QTableWidgetItem *item),但这会导致错误,原因是我更改了插槽中QTableWidgetItem的背景色,然后又递归执行了该插槽,因为itemChanged。

我也尝试过使用信号QTableWidget::itemEntered(QTableWidgetItem *item),但这与某些鼠标事件有关,这实际上对我不起作用。

我尝试过的最后一个方法是重写自定义QTableWidget类中的eventfilter,如下所示:

    bool custom_DropTable::eventFilter(QObject *obj, QEvent *evt)
{
    if (evt->type() == QEvent::KeyPress)
    {
        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(evt);
        if (keyEvent->key() == Qt::Key_Return)
        {
            emit si_itemTextEntered(this->currentItem());
            return true;
        }
        else
        {
            return false;
        }
    }
    else
    {
        return QObject::eventFilter(obj, evt);
    }
}

但是即使按回车键也不能真正到达信号,因此请设置文本。

有人对我有任何建议或改进吗?

最佳答案

您可以使用 QObject::blockSignals 将小部件设置为否以发送信号。这样,您可以使用连接到插槽的信号QTableWidget::itemChanged(QTableWidgetItem* item),该插槽将首先阻塞表的信号,然后更改项目,然后取消阻塞信号。这里有一个最小的例子:

#include <QApplication>
#include <QTableWidget>
#include <QTableWidgetItem>

// Declare table globaly so the slot can block its signals
QTableWidget* table;

// Slot
void itemChanged(QTableWidgetItem* item)
{
  // Block table signals
  table->blockSignals(true);

  // Change item background color
  item->setBackgroundColor(Qt::red);

  // Append text
  item->setText(item->text() + " edited");

  // Unblock signals
  table->blockSignals(false);
}

int main(int argc, char** argv)
{
  // Create application
  QApplication app(argc, argv);

  // Create table
  table = new QTableWidget(3, 4);

  // Add items
  for (int i = 0; i < table->rowCount() * table->columnCount(); i++)
  {
    int row = i / table->columnCount();
    int col = i % table->columnCount();
    table->setItem(row, col, new QTableWidgetItem(QString::number(i)));
  }

  // Connect
  QObject::connect(table, &QTableWidget::itemChanged, itemChanged);

  // Show table
  table->show();

  // Run
  return app.exec();
}

10-06 13:47