PDA

View Full Version : Navigate table cells with down/up arrows while editing a double cell



jmalicke
25th October 2014, 17:59
I have a QTableView with a column of doubles. Since my custom implementations of data and setData operate on doubles it appears Qt automatically provides the QDoubleSpinBox. I would like to be able to navigate through the table cells with the keyboard arrows while editing the double. What happens is that the delegate seems to steal the key down event and uses it to control the spin box rather than navigating to another cell.

wysota
26th October 2014, 11:18
Provide your own editor widget that will ignore the events you don't want intercepted by the editor. They should propagate to the view and be handled there.

jmalicke
26th October 2014, 16:00
I have created my own delegate that renders a QSpinBox. Now how do I do the part that ignores the events?

d_stranz
26th October 2014, 18:33
If your delegate is your own widget derived from QSpinBox, then you would provide event handlers for key press and key release events. In those, you would ignore the up and down arrow keys, but pass everything else to the base class (QSpinBox) for handling.

jmalicke
26th October 2014, 19:30
Hi folks,

Thank you so much for the help!

I have implemented a custom delegate that returns a custom editor. The NavigableDoubleSpinBoxDelegate returns an editor of the type NavigableDoubleSpinBox.


class NavigableDoubleSpinBoxDelegate : public QStyledItemDelegate
{
Q_OBJECT

public:
NavigableDoubleSpinBoxDelegate(QObject * parent = nullptr) : QStyledItemDelegate(parent) {}
virtual QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
virtual void setEditorData(QWidget *editor, const QModelIndex &index) const;
virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
virtual void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,const QModelIndex &index) const;
};

class NavigableDoubleSpinBox : public QDoubleSpinBox
{
public:
NavigableDoubleSpinBox(QWidget * parent = nullptr) : QDoubleSpinBox(parent) {}

protected:
virtual void keyPressEvent(QKeyEvent * event) override;
};

Here is where the custom editor is provided:


QWidget * NavigableDoubleSpinBoxDelegate::createEditor(QWidg et * parent, const QStyleOptionViewItem &, const QModelIndex &) const
{
return new NavigableDoubleSpinBox(parent);
}

The custom editor is set to ignore key ups, downs, lefts and rights and pass every other key to it's parent event handler.


void NavigableDoubleSpinBox::keyPressEvent(QKeyEvent * event)
{
Logger::getLogger().log(Logger::LOG_DEBUG, "Received keyPressEvent");

if (event->key() == Qt::Key_Up
|| event->key() == Qt::Key_Down
|| event->key() == Qt::Key_Left
|| event->key() == Qt::Key_Right)
{
return; // Ignore event;
}

QDoubleSpinBox::keyPressEvent(event);
}

And finally, of course I set the delegate to the column:


NavigableDoubleSpinBoxDelegate * navigableDelegate = new NavigableDoubleSpinBoxDelegate(this);
ui->pairsTable->setItemDelegateForColumn(MomentValuePairTableModel ::COL_VALUE, navigableDelegate);

Unfortunately, what this code accomplishes is that it removes the arrow key functionality for controlling the spinbox. I still don't get the behavior I want -- that the arrows control the position of the selected cell in the QTableView. At this point, is the event supposed to propagate to the QTableView? Am I missing a step somewhere?

wysota
26th October 2014, 20:01
if (event->key() == Qt::Key_Up
|| event->key() == Qt::Key_Down
|| event->key() == Qt::Key_Left
|| event->key() == Qt::Key_Right)
{
return; // Ignore event;
}
This does not ignore the event. This does:


if (event->key() == Qt::Key_Up
|| event->key() == Qt::Key_Down
|| event->key() == Qt::Key_Left
|| event->key() == Qt::Key_Right)
{
event->ignore(); // Ignore event;
return;
}