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
?
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
?
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
model->setData(index,"",Qt::EditRole);
or something else. –
Conveyancer 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_()
© 2022 - 2024 — McMap. All rights reserved.