PDA

View Full Version : QTableWidget KeyPress filtering



grantbj74
5th October 2011, 05:07
Hi,

I have a QTableWidget with one column that can have 0 to 255 entered (all other characters should be ignored). All other columns are read only.

I setup the table to pass events to the main window eventFilter, unfortunately keyPress doesn't make it there keyRelease does.

So I guess I need to catch them from QTableWidgetItem. I tried the following, this was in the program body, maybe I should try similar in constructor? Also I think the item in the connect function probably needs to be *item or &item or something ?



QTableWidgetItem *item;

if((item = new QTableWidgetItem("0")) != NULL) {

table->setItem(row, col, item);
connect(item, SIGNAL(keyPressEvent(QKeyEvent *)), this, SLOT(onKeyPressEvent(QKeyEvent *)));
}

wysota
7th October 2011, 21:46
Why are you using event filters? Use an item delegate.

grantbj74
10th October 2011, 03:35
Thanks, Could you give a little more information or point me to an example?

wysota
10th October 2011, 07:33
QAbstractItemDelegate

grantbj74
13th October 2011, 07:07
Thanks I got the basic key filtering working with the following code.



bool StringDelegate::eventFilter(QObject *obj, QEvent *event)
{
if(event->type() == QEvent::KeyPress) {

QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);

return (keyEvent->key() < '0' || keyEvent->key() > '9');
}
// standard event processing
return QObject::eventFilter(obj, event);
}


Now I am trying to enforce the range when the user exits editing: I tried to add the following to the eventFilter, it compiles but doesn't work.



} else if(event->type() == QEvent::Leave) {

QLineEdit *lineEdit = static_cast<QLineEdit*>(obj);
QString text = lineEdit->text();

if(text.toInt() > 255)
text = "255";
else if(text.toInt() < 1)
text = "0";

lineEdit->setText(text);
}


The following code checks range when editing starts, but i'm just interested in when editing ends:



void StringDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
QString value = index.model()->data(index, Qt::EditRole).toString();
QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);

if(value.toInt() > 255)
value = "255";
else if(value.toInt() < 1)
value = "0";

lineEdit->setText(value);
}


Any ideas? Thanks in advance.

wysota
13th October 2011, 09:03
Why did you fix yourself on using an event filter????? All you need to do is to override QAbstractItemDelegate::createEditor().

grantbj74
18th October 2011, 07:07
Thanks,

So the following code sets the range (0 to 255), using a validator:



QWidget* StringDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &,const QModelIndex &) const
{
QLineEdit *editor = new QLineEdit(parent);
QIntValidator *val = new QIntValidator(editor);

val->setRange(0, 255);
editor->setValidator(val);

return editor;
}


Is there a way to say chop off leading zeros once editing is finished using delegates?

wysota
18th October 2011, 07:23
How about returning a spinbox from createEditor() with a range set to 0-255?

grantbj74
19th October 2011, 04:19
Yes that worked, Thanks



QWidget* StringDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &,const QModelIndex &) const
{
QSpinBox *spin = new QSpinBox(parent);

spin->setRange(0, 255);
return spin;
}