Masa
Masa

Reputation: 11

How to get a signal when a user is typing in a cell in qtablewidget? C++

QtableWidget emits a signal when a cell is changed but what I need is to know when the user is typing.

For example: if the user write "cat" in a cell, I need to get a signal when is written "c", other signal when is written "a" and another third signal when is written "t". "cellChanged" emits the signal only after lefting the cell.

I tried to use a eventFilter but it is not working unfortunately.

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

I tried with this->state()==QAbstractItemView::EditingState but this is a protected member of QAbstractItemView and I do not know how to subclass QTablewidget.

Thank you in advance.

Upvotes: 1

Views: 391

Answers (1)

Erel
Erel

Reputation: 749

Not necessarily the best solution, but I would do something as follows.

• Create a subclass of QWidget or whatever fills your QTableWidget (for clarification purposes, let us name it CellWidget).

• Give this class the signals you want : a_signal(someArgument);, c_signal(someArgument);, t_signal(someArgument);. It requires putting the Q_OBJECT macro in the class definition. Assuming you need some properties of both QTableWidget and something such as QLineEdit (put the latter could be replaced by anything meant to hold text) :

• Override void QWidget::keyPressEvent(QKeyEvent *event) as below.

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(); 
}

• Fill the table with these widgets and connect them to the appropriate 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);
        
    }
    
}

You may not specify an argument for the signal, or use this very argument to do some logic in the slot :

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

You may also check if the CellWidget is in focus in the event (look at QWiget::hasFocus()).

Upvotes: 1

Related Questions