如何在焦点移出时从QTableWidget中移除CellWidget?
解决方案
方法一:给QComboBox安装事件过滤器
动态创建QComboBox时,为它安装事件过滤器捕获QEvent::FocusOut事件:
- 创建ComboBox的代码中添加:
comboBox->installEventFilter(this);(当前类需实现事件过滤器) - 重写
eventFilter函数处理焦点移出:
bool YourClass::eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::FocusOut) { QComboBox *combo = qobject_cast<QComboBox*>(obj); if (combo) { QModelIndex index = ui->tableWidget->indexAt(combo->pos()); if (index.isValid()) { ui->tableWidget->setCellWidget(index.row(), index.column(), nullptr); delete combo; } } } return QObject::eventFilter(obj, event); }
方法二:监听QApplication焦点变化信号
通过全局焦点变化信号覆盖所有焦点移出场景:
- 初始化时连接信号:
connect(qApp, &QApplication::focusChanged, this, [this](QWidget *oldWidget, QWidget *newWidget){ QComboBox *oldCombo = qobject_cast<QComboBox*>(oldWidget); if (oldCombo) { QModelIndex index = ui->tableWidget->indexAt(oldCombo->pos()); if (index.isValid() && ui->tableWidget->cellWidget(index.row(), index.column()) == oldCombo) { ui->tableWidget->setCellWidget(index.row(), index.column(), nullptr); delete oldCombo; } } });
方法三:结合TableWidget当前项变化信号
处理用户点击其他单元格的场景:
connect(ui->tableWidget, &QTableWidget::currentItemChanged, this, [this](QTableWidgetItem *current, QTableWidgetItem *previous){ if (previous) { QWidget *widget = ui->tableWidget->cellWidget(previous->row(), previous->column()); QComboBox *combo = qobject_cast<QComboBox*>(widget); if (combo) { ui->tableWidget->setCellWidget(previous->row(), previous->column(), nullptr); delete combo; } } });
注意事项
- 删除ComboBox前必须调用
setCellWidget设为nullptr,避免TableWidget持有无效指针。 - 确保动态创建的ComboBox在删除前无悬空信号连接。
内容的提问来源于stack exchange,提问作者Shobhit Mittal
相关产品推荐
相关产品推荐

