Planned maintenance has been done but it did not solve the problem. So work will continue on this and a new time for trying updates will be announced asap.

QComboBox in the QTableView



  • Hello everybody! I have some problem with setting QComboBox into QTableView

    I want to use in my test app MVC model. In my code i have my custom Model class - TableModel, it inherits from QAbstractTableModel, View class - it is a standard QTableView, and custom Delegate - SimpleDelegate, It inherits from QStyledItemDelegate.

    But after compilation i can't see any QComboBox on QTableView! After doubleclick I see only QLine Edit.

    This is code of my app:

    main.cpp

    #include <QtWidgets>
    #include <QObject>
    #include "simpledelegate.h"
    #include "tablemodel.h"
     
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
        TableModel model(200, 200);
     
        QTableView tableView;
        tableView.setModel(&model);
        tableView.setItemDelegate(new SimpleDelegate(&tableView));
        tableView.viewport()->setAttribute(Qt::WA_Hover);
        tableView.show();
        return app.exec();
    }
    

    simple.h

    #ifndef SIMPLEDELEGATE
    #define SIMPLEDELEGATE
     
    #include <QWidget>
    #include <QStyledItemDelegate>
    #include <QComboBox>
    #include <QObject>
     
    class SimpleDelegate : public QStyledItemDelegate
    {
        Q_OBJECT
    public:
        SimpleDelegate(QObject* pobj = 0);
        QWidget* createEditor(QWidget *parent,
                                    const QStyleOptionViewItem &option,
                                    const QModelIndex &index);
     
        void setModelData(QWidget *editor, QAbstractItemModel *model,
                                                 const QModelIndex &index);
        void setEditorData(QWidget *editor, const QModelIndex &index);
    };
    #endif // SIMPLEDELEGATE
    

    simple.cpp

    #include "simpledelegate.h"
     
    SimpleDelegate::SimpleDelegate(QObject* pobj) : QStyledItemDelegate(pobj)
    {
    }
    QWidget*  SimpleDelegate::createEditor(QWidget *parent,
                                const QStyleOptionViewItem &option,
                                const QModelIndex &index)
    {
     
        QStringList values;
        values << "Enabled" << "Disabled";
     
        QComboBox* comboBox = new QComboBox(parent);
        comboBox->addItems(values);
        return comboBox;
     
    }
     
    void  SimpleDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
                                             const QModelIndex &index)
    {
        QComboBox* comboBox = qobject_cast<QComboBox*>(editor);
        QString value = comboBox->currentText();
        model->setData(index, value, Qt::EditRole);
    }
     
    void  SimpleDelegate::setEditorData(QWidget *editor, const QModelIndex &index)
    {
        QString value = index.model()->data(index, Qt::EditRole).toString();
        //qDebug() << "Value:" << value;
        QComboBox* comboBox = qobject_cast<QComboBox*>(editor);
        comboBox->setCurrentIndex(comboBox->findText(value));
    }
    

    table.h

    #ifndef TABLEMODEL
    #define TABLEMODEL
     
    #include <QWidget>
    #include <QStyledItemDelegate>
    #include <QComboBox>
    #include <QObject>
     
    class TableModel : public QAbstractTableModel
    {
        Q_OBJECT
    private:
        int                          m_nRows;
        int                          m_nColumns;
        QHash<QModelIndex, QVariant> m_hash;
     
    public:
        TableModel(int nRows, int nColumns, QObject* pobj = 0);
     
        QVariant data(const QModelIndex& index, int nRole) const;
     
        bool setData(const QModelIndex& index,
                     const QVariant&    value,
                     int                nRole
                    );
     
        int rowCount(const QModelIndex&) const ;
        int columnCount(const QModelIndex&) const ;
     
        Qt::ItemFlags flags(const QModelIndex& index) const;
    };
     
    #endif // TABLEMODEL
    

    table.cpp

    #include "tablemodel.h"
     
     
     
    TableModel::TableModel(int nRows, int nColumns, QObject* pobj)
        : QAbstractTableModel(pobj)
        , m_nRows(nRows)
        , m_nColumns(nColumns)
    {
    }
     
    QVariant TableModel::data(const QModelIndex& index, int nRole) const
    {
        if (!index.isValid())
        {
            return QVariant();
        }
        QString str = QString("%1,%2").arg(index.row() + 1).arg(index.column() + 1);
        return (nRole == Qt::DisplayRole || nRole == Qt::EditRole)
               ? m_hash.value(index, QVariant(str))
               : QVariant();
    }
     
    bool TableModel::setData(const QModelIndex& index,
                 const QVariant&    value,
                 int                nRole
                )
    {
        if (index.isValid() && nRole == Qt::EditRole) {
            m_hash[index] = value;
            emit dataChanged(index, index);
            return true;
        }
        return false;
    }
     
    int TableModel::rowCount(const QModelIndex&) const
    {
        return m_nRows;
    }
     
    int TableModel::columnCount(const QModelIndex&) const
    {
        return m_nColumns;
    }
     
    Qt::ItemFlags TableModel::flags(const QModelIndex& index) const
    {
        Qt::ItemFlags flags = QAbstractTableModel::flags(index);
        return index.isValid() ? (flags | Qt::ItemIsEditable)
                               : flags;
    }
    

    Where is mistake?
    Thanks!

    P.S. Sorry for my poor English



  • Hi,

    When you reimplemented the virtual methods setEditorData, setModelData and createEditor, you simply forgot the "const" at the end:

    QWidget* SimpleDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const {
      QStringList values;
      values << "Enabled" << "Disabled";
    
      QComboBox* comboBox = new QComboBox(parent);
      comboBox->addItems(values);
      return comboBox;
    }
    
    void SimpleDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const {
      QComboBox* comboBox = qobject_cast<QComboBox*>(editor);
      QString value = comboBox->currentText();
      model->setData(index, value, Qt::EditRole);
    }
    
    void SimpleDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const {
      QString value = index.model()->data(index, Qt::EditRole).toString();
      QComboBox* comboBox = qobject_cast<QComboBox*>(editor);
      comboBox->setCurrentIndex(comboBox->findText(value));
    }
    
    

    If you can, try to use C++11 and add the "override" keyword at the end of the methods in your header files. Then the compiler would tell you if the overridden method is really a method to override.

    QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
    void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
    void setEditorData(QWidget *editor, const QModelIndex &index) const override;
    

    Now it works, but obviously it replaces the integer value with "enable" or "disable". Not sure that was what you wanted.


Log in to reply