Unsolved 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.