【问题标题】:How to get a signal when a user is typing in a cell in qtablewidget? C++当用户在 qtablewidget 中输入单元格时如何获取信号? C++
【发布时间】:2020-11-16 02:56:25
【问题描述】:

QtableWidget 在单元格更改时会发出信号,但我需要知道用户何时键入。

例如:如果用户在一个单元格中写入“cat”,我需要在写入“c”时获取一个信号,在写入“a”时获取另一个信号,在写入“t”时获取另一个第三个信号。 "cellChanged" 只有在离开单元格后才会发出信号。

我尝试使用 eventFilter,但不幸的是它不起作用。

bool Matrix::eventFilter(QObject *object, QEvent *event)
{
   if (object == ui->tableWidget && event->type() == QEvent::KeyPress)
   {
      ...
   } 
}

我尝试使用this->state()==QAbstractItemView::EditingState,但这是 QAbstractItemView 的受保护成员,我不知道如何继承 QTablewidget。

提前谢谢你。

【问题讨论】:

  • “它不工作”如何?它是否没有编译或给出一些运行时错误或运行正常但什么都不做?
  • 它运行正常,但是当我写东西时它不会在这种情况下进入“if (object == ui->tableWidget && event->type() == QEvent::KeyPress)”在 qtablewidget underscore_d
  • 信息here 可能有帮助吗?
  • 谢谢,但它对我不起作用,因为他们解决了阻塞信号
  • @Masa 有什么消息吗?你找到解决办法了吗?

标签: c++ qtablewidget


【解决方案1】:

不一定是最好的解决方案,但我会做以下事情。

• 创建 QWidget 的子类或任何填充您的 QTableWidget 的东西(为了清楚起见,我们将其命名为 CellWidget)。

• 给这个类你想要的signals:a_signal(someArgument);c_signal(someArgument);t_signal(someArgument);。 它需要将Q_OBJECT 宏放在类定义中。 假设您需要 QTableWidgetQLineEdit 之类的某些属性(将后者可以替换为任何用于保存文本的内容):

• 覆盖void QWidget::keyPressEvent(QKeyEvent *event),如下所示。

class CellWidget : public QTableWidgetItem , public QLineEdit{

    Q_OBJECT

protected :
    
    void keyPressEvent(QKeyEvent *event) override;
    
public signals :

//Declaration of the signals

}
void CellWidget::keyPressEvent(QKeyEvent *event){

    switch(event->key()){
        
        case(Qt::Key_A):{
        emit(a_signal(someArgumentWithCorrectType));
        break;
        }
        
        //etc.
        
        default:{break;}

    }

    ParentClass::keyPressEvent(event); //Processes the event as seen from the parent class
    event->accept(); 
}

• 用这些小部件填充表格并将它们连接到适当的slot

for(int i = 0 ; i < table->rowCount() ; i++){
    
    for(int j = 0 ; j < table->columnCount() ; j++){
        
        CellWidget *cw = new CellWidget(table);
        connect(cw , &CellWidget::a_signal , someWidget , &SomeWidget::someSlotA);
        connect(cw , &CellWidget::c_signal , someWidget , &SomeWidget::someSlotC);
        connect(cw , &CellWidget::t_signal , someWidget , &SomeWidget::someSlotT);
        table->setCellWidget(i , j  , cw);
        
    }
    
}

你不能为信号指定一个参数,或者使用这个参数在槽中做一些逻辑:

void SomeWidget::SomeSlot(int key){
    
    
    switch(key){
        
        case(...):{
            ...
            break;
        }
        
    }
    
}

您还可以检查 CellWidget 是否在事件中处于焦点位置(查看QWiget::hasFocus())。

【讨论】:

  • 感谢您的回答。我使用了 Qtablewidgetitem 的许多功能,我希望我能找到其他解决方案,而无需创建 QWidget 的子类。但如果我找不到其他解决方案,我会应用你的方法
  • 为什么不把 CellWidget 作为 QWidget (或 QLineEdit 或任何包含文本的东西)和 QTableWidgetItem 的子类?使用这种方法(双重继承),您甚至可以通过覆盖适当的事件处理程序来解决您在其他问题中遇到的问题。
  • 再次感谢您!我尝试应用您的建议,但收到以下错误:静态断言失败:类中没有 Q_OBJECT 信号为 Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro::Value, ^
  • 如果我没记错的话,你必须在你的类中添加Q_OBJECT 宏才能为它分配信号和插槽。我更新了答案以添加类声明。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-28
  • 2023-03-10
相关资源
最近更新 更多