Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Solved Qtableview Combobox in columns

    General and Desktop
    5
    18
    1231
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • N
      n-2204 last edited by n-2204

      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

      VRonin 1 Reply Last reply Reply Quote 0
      • VRonin
        VRonin last edited by

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

        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
        ~Napoleon Bonaparte

        On a crusade to banish setIndexWidget() from the holy land of Qt

        1 Reply Last reply Reply Quote 1
        • VRonin
          VRonin @n-2204 last edited by

          @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

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          N 1 Reply Last reply Reply Quote 2
          • N
            n-2204 @VRonin last edited by

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

            1 Reply Last reply Reply Quote 0
            • VRonin
              VRonin last edited by VRonin

              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;
              

              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
              ~Napoleon Bonaparte

              On a crusade to banish setIndexWidget() from the holy land of Qt

              N 1 Reply Last reply Reply Quote 2
              • N
                n-2204 @VRonin last edited by

                @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()

                1 Reply Last reply Reply Quote 0
                • VRonin
                  VRonin last edited by

                  https://doc.qt.io/qt-5/qcombobox.html#modelColumn-prop

                  just call setModelColumn()

                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                  ~Napoleon Bonaparte

                  On a crusade to banish setIndexWidget() from the holy land of Qt

                  1 Reply Last reply Reply Quote 1
                  • N
                    n-2204 last edited by

                    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?

                    1 Reply Last reply Reply Quote 0
                    • SGaist
                      SGaist Lifetime Qt Champion last edited by

                      Hi,

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

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      1 Reply Last reply Reply Quote 1
                      • N
                        n-2204 last edited by

                        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

                        1 Reply Last reply Reply Quote 0
                        • VRonin
                          VRonin last edited by

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

                          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                          ~Napoleon Bonaparte

                          On a crusade to banish setIndexWidget() from the holy land of Qt

                          1 Reply Last reply Reply Quote 1
                          • N
                            n-2204 last edited by

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

                            JonB 1 Reply Last reply Reply Quote 0
                            • JonB
                              JonB @n-2204 last edited by JonB

                              @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... :)

                              N 1 Reply Last reply Reply Quote 1
                              • N
                                n-2204 @JonB last edited by

                                @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);
                                }
                                
                                1 Reply Last reply Reply Quote 0
                                • VRonin
                                  VRonin last edited by

                                  ui.tableView_2->setIndexWidget

                                  No God, NOOOOOOO!

                                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                  ~Napoleon Bonaparte

                                  On a crusade to banish setIndexWidget() from the holy land of Qt

                                  N 1 Reply Last reply Reply Quote 0
                                  • nagesh
                                    nagesh last edited by

                                    @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

                                    1 Reply Last reply Reply Quote 0
                                    • N
                                      n-2204 @VRonin last edited by n-2204

                                      @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

                                      VRonin 1 Reply Last reply Reply Quote 0
                                      • VRonin
                                        VRonin @n-2204 last edited by VRonin

                                        @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

                                        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                        ~Napoleon Bonaparte

                                        On a crusade to banish setIndexWidget() from the holy land of Qt

                                        N 1 Reply Last reply Reply Quote 1
                                        • N
                                          n-2204 @VRonin last edited by

                                          @VRonin 😃 ok thanks

                                          1 Reply Last reply Reply Quote 0
                                          • First post
                                            Last post