Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Qtableview Combobox in columns



  • 749ca5e0-dd78-4358-baf5-f9519f0c9b91-image.png
    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 of addItems



  • @VRonin but model1 need to take from base class (where i created table)
    so how to get that model?



  • 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;
    


  • @VRonin in table2 combobox values should be from my table1 column 2.
    so how can i store/get that values and pass as combobox->setmodel()





  • Not working
    the values in combobox should come from table1 column 2
    and in table2 column 1 and 2 comobox should create
    how to do this?


  • Lifetime Qt Champion

    Hi,

    Please take the time to read the documentation of the classes you are using: QComboBox::setModelColumn.



  • Hi,
    Anyone one example/code of Qtableview Combobox in columns
    please share
    the values in combobox should come from table1 column 2
    and in table2 column 1 and 2 comobox should create
    Thanks



  • #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();
    }
    
    


  • Thanks
    Is there another way to add combobox in Qtableview using setcellwidget
    or its there for only tablewidget not tableview?



  • @n-2204
    As you can see from docs setCellWidget() is QTableWidget only, not QTableView. Though the latter does have equivalent setIndexWidget() instead.

    But I can warn you now that if you use setCellWidget() or setIndexWidget() at all @VRonin will come down on you like a ton of bricks (look at his sig!) ;-) Which is why he showed you code using QStyledItemDelegate 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);
    }


  • ui.tableView_2->setIndexWidget

    No God, NOOOOOOO!



  • @n-2204 Refer to Spin Box Delegate Example in QT
    https://doc.qt.io/qt-5/qtwidgets-itemviews-spinboxdelegate-example.html
    same concept for Combobox as well



  • @VRonin 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 example



  • @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 example

    what 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



  • @VRonin 😃 ok thanks


Log in to reply