Qtableview Combobox in columns
-
Qtableview and combobox added in column using delegate approach
I have two tables and i created combobox in table 2,
QWidget* QItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option,
const QModelIndex& index) const {
QStringList values;//combobox
values << "Value1" << "Value2" << "Value3" << "Value4";
QComboBox* comboBox = new QComboBox(parent);
comboBox->addItems(values);
return comboBox;
}
but first thing combobox shows when i select the column how to correct it ?
and second i need pass values in combobox whatever i have data in my table1 Name column (so whenever user add table1 name, same should update as combobox value in table2) ?
Thanks in advance -
#include <QApplication> #include <QDebug> #include <QStyledItemDelegate> #include <QTableView> #include <QStandardItemModel> #include <QHBoxLayout> #include <QComboBox> class ComboDelegate : public QStyledItemDelegate{ Q_DISABLE_COPY(ComboDelegate) public: ComboDelegate(QObject* parent = nullptr) :QStyledItemDelegate(parent) ,m_comboModel(nullptr) ,m_comboColumn(0) {} QAbstractItemModel *comboModel() const{return m_comboModel;} void setComboModel(QAbstractItemModel *comboModel){m_comboModel = comboModel;} int comboColumn() const{return m_comboColumn;} void setComboColumn(int comboColumn){m_comboColumn = comboColumn;} QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &) const override{ QComboBox* result = new QComboBox(parent); if(m_comboModel){ result->setModel(m_comboModel); result->setModelColumn(m_comboColumn); } result->setGeometry(option.rect); return result; } void setEditorData(QWidget *editor, const QModelIndex &index) const override{ QComboBox* result = qobject_cast<QComboBox*>(editor); result->setCurrentIndex(result->findData(index.data(),Qt::EditRole)); } void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override{ QComboBox* result = qobject_cast<QComboBox*>(editor); model->setData(index,result->currentData(Qt::EditRole),Qt::EditRole); } void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const override { editor->setGeometry(option.rect); } private: QAbstractItemModel* m_comboModel; int m_comboColumn; }; int main(int argc, char *argv[]) { QApplication app(argc,argv); QWidget wid; QAbstractItemModel* table1 = new QStandardItemModel(&wid); table1->insertColumns(0,2); table1->insertRows(0,10); for(int i=0;i<table1->rowCount();++i){ table1->setData(table1->index(i,0),i+1); table1->setData(table1->index(i,1),QChar('A'+i+1)); } QAbstractItemModel* table2 = new QStandardItemModel(&wid); table2->insertColumns(0,2); table2->insertRows(0,10); for(int i=0;i<table2->rowCount();++i){ table2->setData(table2->index(i,0),i+100); table2->setData(table2->index(i,1),QChar('a'+i+1)); } QAbstractItemModel* table3 = new QStandardItemModel(&wid); table3->insertColumns(0,2); table3->insertRows(0,10); QTableView* table1View = new QTableView(&wid); table1View->setModel(table1); QTableView* table2View = new QTableView(&wid); table2View->setModel(table2); QTableView* table3View = new QTableView(&wid); table3View->setModel(table3); ComboDelegate* delegate1 = new ComboDelegate(table3); delegate1->setComboModel(table1); delegate1->setComboColumn(1); ComboDelegate* delegate2 = new ComboDelegate(table3); delegate2->setComboModel(table2); delegate2->setComboColumn(0); table3View->setItemDelegateForColumn(0,delegate1); table3View->setItemDelegateForColumn(1,delegate2); QHBoxLayout* lay = new QHBoxLayout(&wid); lay->addWidget(table1View); lay->addWidget(table2View); lay->addWidget(table3View); wid.show(); return app.exec(); }
-
@n-2204 said in Qtableview Combobox in columns:
but first thing combobox shows when i select the column how to correct it ?
Yes, if you want to appear as a combobox always you also have to reimplement
paint()
second i need pass values in combobox whatever i have data in my table1 Name column (so whenever user add table1 name, same should update as combobox value in table2) ?
Super easy just call
comboBox->setModel(model1);
instead ofaddItems
-
pass it to the delegate... just create a variable, a getter and a setter in the delegate:
public: void setComboModel(QAbstractItemModel* mdl){m_comboModel =mdl;} QAbstractItemModel* comboModel() const {return m_comboModel ;} private: QAbstractItemModel* m_comboModel = nullptr;
-
https://doc.qt.io/qt-5/qcombobox.html#modelColumn-prop
just call
setModelColumn()
-
Hi,
Please take the time to read the documentation of the classes you are using: QComboBox::setModelColumn.
-
#include <QApplication> #include <QDebug> #include <QStyledItemDelegate> #include <QTableView> #include <QStandardItemModel> #include <QHBoxLayout> #include <QComboBox> class ComboDelegate : public QStyledItemDelegate{ Q_DISABLE_COPY(ComboDelegate) public: ComboDelegate(QObject* parent = nullptr) :QStyledItemDelegate(parent) ,m_comboModel(nullptr) ,m_comboColumn(0) {} QAbstractItemModel *comboModel() const{return m_comboModel;} void setComboModel(QAbstractItemModel *comboModel){m_comboModel = comboModel;} int comboColumn() const{return m_comboColumn;} void setComboColumn(int comboColumn){m_comboColumn = comboColumn;} QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &) const override{ QComboBox* result = new QComboBox(parent); if(m_comboModel){ result->setModel(m_comboModel); result->setModelColumn(m_comboColumn); } result->setGeometry(option.rect); return result; } void setEditorData(QWidget *editor, const QModelIndex &index) const override{ QComboBox* result = qobject_cast<QComboBox*>(editor); result->setCurrentIndex(result->findData(index.data(),Qt::EditRole)); } void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override{ QComboBox* result = qobject_cast<QComboBox*>(editor); model->setData(index,result->currentData(Qt::EditRole),Qt::EditRole); } void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const override { editor->setGeometry(option.rect); } private: QAbstractItemModel* m_comboModel; int m_comboColumn; }; int main(int argc, char *argv[]) { QApplication app(argc,argv); QWidget wid; QAbstractItemModel* table1 = new QStandardItemModel(&wid); table1->insertColumns(0,2); table1->insertRows(0,10); for(int i=0;i<table1->rowCount();++i){ table1->setData(table1->index(i,0),i+1); table1->setData(table1->index(i,1),QChar('A'+i+1)); } QAbstractItemModel* table2 = new QStandardItemModel(&wid); table2->insertColumns(0,2); table2->insertRows(0,10); for(int i=0;i<table2->rowCount();++i){ table2->setData(table2->index(i,0),i+100); table2->setData(table2->index(i,1),QChar('a'+i+1)); } QAbstractItemModel* table3 = new QStandardItemModel(&wid); table3->insertColumns(0,2); table3->insertRows(0,10); QTableView* table1View = new QTableView(&wid); table1View->setModel(table1); QTableView* table2View = new QTableView(&wid); table2View->setModel(table2); QTableView* table3View = new QTableView(&wid); table3View->setModel(table3); ComboDelegate* delegate1 = new ComboDelegate(table3); delegate1->setComboModel(table1); delegate1->setComboColumn(1); ComboDelegate* delegate2 = new ComboDelegate(table3); delegate2->setComboModel(table2); delegate2->setComboColumn(0); table3View->setItemDelegateForColumn(0,delegate1); table3View->setItemDelegateForColumn(1,delegate2); QHBoxLayout* lay = new QHBoxLayout(&wid); lay->addWidget(table1View); lay->addWidget(table2View); lay->addWidget(table3View); wid.show(); return app.exec(); }
-
@n-2204
As you can see from docssetCellWidget()
isQTableWidget
only, notQTableView
. Though the latter does have equivalentsetIndexWidget()
instead.But I can warn you now that if you use
setCellWidget()
orsetIndexWidget()
at all @VRonin will come down on you like a ton of bricks (look at his sig!) ;-) Which is why he showed you code usingQStyledItemDelegate
instead... :) -
@JonB ok so diff part is how to pass the other column values in combobox as using delegate it is easier
/* for (int i = 0, maxI = ui.tableView_2->model()->rowCount();i <= maxI;++i) { QComboBox* combo = new QComboBox(); combo->addItem("value1"); combo->addItem("value2"); combo->addItem("value3"); ui.tableView_2->setIndexWidget(ui.tableView_2->model()->index(i, 1), combo); }
-
@n-2204 said in Qtableview Combobox in columns:
what i have shared code is working
ya thing is how to pass column value in that combobox like what you have shared in combodelegate examplewhat you shared is a shoebox with wheels and you are asking how to put an engine in it to turn it into a car.
The correct way to do it is with a delegate. I shared a full working example using a delegate