Sections

How can I make the tab key go from an editable combotableitem to the next cell in a QTable?


Answer:

The QComboTableItem's lineedit is 'eating' the tab key press which is preventing it from being passed on to the QTable. What you need to do in order to allow it to be processed by the QTable is to listen for the key press and pass it on to the QTable's event filter to process. The following example shows how to do this:

#include <qapplication.h>
#include <qtable.h>
#include <qlineedit.h>
#include <qcombobox.h>
#include <qevent.h>

class MyTable : public QTable
{
public:
MyTable(int r, int c, QWidget *parent = 0) : QTable(r, c, parent) {}
protected:
bool eventFilter( QObject* o, QEvent* e )
{
QObject *obj = o;
bool isCombo = o->isA("QComboBox");
if( !isCombo )
{
if (o->isA("QLineEdit")) {
QLineEdit* le = (QLineEdit *)o;
if( le ) {
isCombo = le->parent()->isA("QComboBox");
if (isCombo)
obj = le->parent();
}
}
}

bool isTab = e->type() == QEvent::KeyPress && (( QKeyEvent*)e)->key() == Key_Tab;
if( isCombo && !isTab )
return false;

return QTable::eventFilter( obj, e );
}
};

class MyComboTableItem : public QComboTableItem
{
public:
MyComboTableItem( QTable* t, const QStringList& l, bool editable = true )
: QComboTableItem( t, l, editable )
{
}

QWidget* createEditor() const
{
QWidget* cb = QComboTableItem::createEditor();
cb->installEventFilter( table() );
((QComboBox*)cb)->lineEdit()->installEventFilter( table() );
return cb;
}
};

int main(int argc, char **argv)
{
QApplication a(argc, argv);
MyTable t(10, 10, 0);
a.setMainWidget(&t);
t.setItem(1, 1, new MyComboTableItem(&t, QStringList("Foo")));
t.show();
return a.exec();

}

Basically what happens is that the event filter will ensure that if the widget that gets the Tab key is the lineedit on the combobox in the cell then it will call the QTable::eventFilter() saying that the event is actually for the QComboBox. This means that it will be processed as a tab key changing the focus, rather than a tab key putting in a tab inside the editor.

back