Reputation: 11
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
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 signal
s 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