Search code examples
qtqtableviewqvalidator

Validating user input in a QTableView


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?


Solution

  • 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