PDA

View Full Version : QTableView tab focus on cell widget



hispeedsurfer
2nd August 2013, 08:27
Hello,

I have setup a QTableView with my own delegate to create a cell widget. This widget contains two QDateTimeEdit elements. My problem if I tab through date/time values of first widget is that the focus leave the cell after last time value, close the editor and enter the next cell.

How can I prevent this behavior and set focus to next QDateTimeEdit widget of the same cell?

hispeedsurfer
2nd August 2013, 11:13
Here the dual value editor that is instantiated in delegate.createEditor method with


QWidget * QStyledItemDelegate::createEditor ( QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index )
{
return new EvaDualValEditor(new QDateTimeEdit(parent), new QDateTimeEdit(parent), parent);
}

... and it looks like in table edit mode. After tabbing (cursor on blue marked) the editor is closed and the next cell is selected.
9388




// header
class EvaDualValEditor : public QWidget
{
Q_OBJECT

public:
explicit EvaDualValEditor(QWidget* editor1, QWidget* editor2, QWidget *parent = 0);
~EvaDualValEditor();

void setValues( QVariant& param1, QVariant& param2 );

protected:

private:
QHBoxLayout *horizontalLayout_2;
QLabel *label;
QWidget *wgt1;
QLabel *label_2;
QWidget *wgt2;

void init();
};

// implementation

EvaDualValEditor::EvaDualValEditor(QWidget* editor1, QWidget* editor2, QWidget* parent /*= 0*/)
: QWidget(parent)
, wgt1(editor1)
, wgt2(editor2)
{
init();
}

EvaDualValEditor::~EvaDualValEditor()
{
}

void EvaDualValEditor::init()
{

setFocusPolicy (Qt::StrongFocus);
setFocusProxy(wgt1);
setTabOrder(wgt1, wgt2);setObjectName(QString::fromUtf8("EvaDualValEditor"));

horizontalLayout_2 = new QHBoxLayout(this);
horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2"));
horizontalLayout_2->setSpacing(1);
horizontalLayout_2->setContentsMargins(1, 1, 1, 1);

label = new QLabel(this);
label->setObjectName(QString::fromUtf8("label"));

horizontalLayout_2->addWidget(label);

wgt1->setObjectName(QString::fromUtf8("widget"));

horizontalLayout_2->addWidget(wgt1);

label_2 = new QLabel(this);
label_2->setObjectName(QString::fromUtf8("label_2"));

horizontalLayout_2->addWidget(label_2);

wgt2->setObjectName(QString::fromUtf8("widget_2"));

horizontalLayout_2->addWidget(wgt2);

}

void EvaDualValEditor::setValues( QVariant& param1, QVariant& param2 )
{
if (wgt1 && !param1.isNull())
{
qobject_cast<QDateTimeEdit*>(wgt1)->setDateTime(param1.toDateTime());
}
if (wgt2 && !param2.isNull())
{
qobject_cast<QDateTimeEdit*>(wgt2)->setDateTime(param2.toDateTime());
}
}

Santosh Reddy
3rd August 2013, 08:40
Use
QTableView::setTabKeyNavigation(false);

hispeedsurfer
8th October 2013, 14:30
Hi,

here now a part of my solution.

Delegate

QWidget* TableDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
if (index.row()%2 && (index.column()==1 || index.column()==2))
{
EvaDualValEditor* dualValEditor = new EvaDualValEditor(new QDateTimeEdit(parent), new QDateTimeEdit(parent), parent);
connect(dualValEditor, SIGNAL(commitData(QWidget*)), this, SIGNAL(commitData(QWidget*)));
connect(dualValEditor, SIGNAL(closeEditor(QWidget*, QAbstractItemDelegate::EndEditHint)), this, SIGNAL(closeEditor(QWidget*, QAbstractItemDelegate::EndEditHint)));
return dualValEditor;
}
return QStyledItemDelegate::createEditor(parent, option, index);
}

DualValEditor

EvaDualValEditor::EvaDualValEditor( QWidget* editor1, QWidget* editor2, QWidget *parent)
: QWidget(parent)
, wgt1(editor1)
, wgt2(editor2)
{
if (editor1 && editor2)
{
init();

setFocusPolicy(Qt::StrongFocus);
setFocusProxy(wgt1);
setTabOrder(wgt1, wgt2);
wgt1->installEventFilter(this);
wgt2->installEventFilter(this);
}
}


bool EvaDualValEditor::focusNextPrevChild( bool next )
{
Qt::FocusReason reason = next ? Qt::TabFocusReason : Qt::BacktabFocusReason;

if (next)
{
if (wgt1->hasFocus())
{
wgt2->setFocus(reason);
return true;
}
else if(wgt2->hasFocus())
{
QWidget* tmp = focusProxy();
setFocusProxy(wgt2);
emit commitData(this);
emit closeEditor(this, QAbstractItemDelegate::EditNextItem);
setFocusProxy(tmp);
return true;
}
}
else if(!next)
{
if (wgt2->hasFocus())
{
wgt1->setFocus(reason);
return true;
}
else if(wgt1->hasFocus())
{
emit commitData(this);
emit closeEditor(this, QAbstractItemDelegate::EditPreviousItem);
return true;
}
}

return QWidget::focusNextPrevChild(next);
}

This works exactly as desired. :)