I have a QTableView
and I want to validate user input.
If user insert an invalid value in a cell of the QTableView
, I want to highlight that cell and disable a QPushButton
.
How can I achieve this? Can I use QValidator
?
Input validation is the process of testing input received by the application for compliance against a standard defined within the application. It can be as simple as strictly typing a parameter and as complex as using regular expressions or business logic to validate input.
Input validation (also known as data validation) is the proper testing of any input supplied by a user or application. Input validation prevents improperly formed data from entering an information system.
Input validation strategies It is always recommended to prevent attacks as early as possible in the processing of the user's (attacker's) request. Input validation can be used to detect unauthorized input before it is processed by the application.
Yes, you can do this, use custom QItemDelegate
for this purpose (I used QIntValidator
just as example).
Header:
#ifndef ITEMDELEGATE_H
#define ITEMDELEGATE_H
#include <QItemDelegate>
class ItemDelegate : public QItemDelegate
{
Q_OBJECT
public:
explicit ItemDelegate(QObject *parent = 0);
protected:
QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void setEditorData(QWidget * editor, const QModelIndex & index) const;
void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const;
void updateEditorGeometry(QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index) const;
signals:
public slots:
};
#endif // ITEMDELEGATE_H
Cpp
#include "itemdelegate.h"
#include <QLineEdit>
#include <QIntValidator>
ItemDelegate::ItemDelegate(QObject *parent) :
QItemDelegate(parent)
{
}
QWidget *ItemDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QLineEdit *editor = new QLineEdit(parent);
editor->setValidator(new QIntValidator);
return editor;
}
void ItemDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
QString value =index.model()->data(index, Qt::EditRole).toString();
QLineEdit *line = static_cast<QLineEdit*>(editor);
line->setText(value);
}
void ItemDelegate::setModelData(QWidget *editor,
QAbstractItemModel *model,
const QModelIndex &index) const
{
QLineEdit *line = static_cast<QLineEdit*>(editor);
QString value = line->text();
model->setData(index, value);
}
void ItemDelegate::updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
editor->setGeometry(option.rect);
}
Usage:
#include "itemdelegate.h"
//...
ItemDelegate *itDelegate = new ItemDelegate;
ui->tableView->setItemDelegate(itDelegate);
In this case user will not be able input wrong data, but you can use next:
void ItemDelegate::setModelData(QWidget *editor,
QAbstractItemModel *model,
const QModelIndex &index) const
{
QLineEdit *line = static_cast<QLineEdit*>(editor);
QIntValidator validator;
int pos = 0;
QString data = line->text();
if(validator.validate(data,pos) != QValidator::Acceptable)
{
qDebug() << "not valid";//do something
}
else
{
model->setData(index, data);
}
}
But in this case don't forget remove editor->setValidator(new QIntValidator);
line from your code
I worked through the PyQt/PySide implementation of Kosovan's answer. I am including the python code here for those who are not working in C++:
from PySide2 import QtWidgets, QtCore, QtGui
class ItemDelegate(QtWidgets.QItemDelegate):
def __init__(self, parent):
super().__init__(parent)
def createEditor(self, parent, option, index):
editor = QtWidgets.QLineEdit(parent)
editor.setValidator(QtGui.QIntValidator())
return editor
def setEditorData(self, editor, index):
value = str(index.model()._data[index.row()][index.column()])
editor.setText(value)
def setModelData(self, editor, model, index):
model.setData(index, editor.text(), QtCore.Qt.EditRole)
def updateEditorGeometry(self, editor, option, index):
editor.setGeometry(option.rect)
class TableModel(QtCore.QAbstractTableModel):
def __init__(self, data):
super().__init__()
self._data = data
def data(self, index, role):
if role == QtCore.Qt.DisplayRole:
return str(self._data[index.row()][index.column()])
def rowCount(self, index):
return len(self._data)
def columnCount(self, index):
return len(self._data[0])
def setData(self, index, value, role):
if role == QtCore.Qt.EditRole:
try:
value = int(value)
except ValueError:
return False
self._data[index.row()][index.column()] = value
return True
return False
def flags(self, index):
return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
data = [
[1, 2],
[3, 4],
[5, 6],
]
self.model = TableModel(data)
self.table = QtWidgets.QTableView()
self.table.setModel(self.model)
self.table.setItemDelegate(ItemDelegate(self))
self.setCentralWidget(self.table)
if __name__ == '__main__':
app = QtWidgets.QApplication()
win = MainWindow()
win.show()
app.exec_()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With