Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Combobox in Qtableview
Forum Updated to NodeBB v4.3 + New Features

Combobox in Qtableview

Scheduled Pinned Locked Moved Solved General and Desktop
47 Posts 6 Posters 9.8k Views 3 Watching
  • 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 Offline
    N Offline
    n-2204
    wrote on last edited by
    #9

    using this rowinserted signal even not going on this slot

    connect(ui.tableView->model(), SIGNAL(rowsInserted), ui.tableView_2->model(), SLOT(changedvalue()));
    
    void tool::changedvalue()
    {
    QAbstractItemModel* table1 = ui.tableView->model();
    QAbstractItemModel* table2 = ui.tableView_2->model();
    for (int i = 0, maxI = table2->rowCount();i <= maxI;++i)//combobox in table2 col1
    {
        for (int r = 0, maxI = table1->rowCount();r < maxI;++r)//getvalue fromtable1
        {
            QComboBox* combo = new QComboBox();
            QString list1[10] = { table1->data(table1->index(r, 0)).toString() };//store value in list
            qDebug() << "combox values1" ;
            for (int j = 0; j < 10; j++)
            {
                  combo->addItem(list1[j]);/pass list to combobox
                qDebug() << "combox values" << list1[j];/
            }
            ui.tableView_2->setIndexWidget(ui.tableView_2->model()->index(i, 1), combo);
        }      
    }
    }
    
    1 Reply Last reply
    0
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #10

      @n-2204 said in Combobox in Qtableview:

      connect(ui.tableView->model(), SIGNAL(rowsInserted), ui.tableView_2->model(), SLOT(changedvalue()));

      This is wrong - again: use the new signal/slot syntax to catch such errors on compile time. And if you don't want then watch the output to stdout during debugging!

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      JonBJ 1 Reply Last reply
      4
      • Christian EhrlicherC Christian Ehrlicher

        @n-2204 said in Combobox in Qtableview:

        connect(ui.tableView->model(), SIGNAL(rowsInserted), ui.tableView_2->model(), SLOT(changedvalue()));

        This is wrong - again: use the new signal/slot syntax to catch such errors on compile time. And if you don't want then watch the output to stdout during debugging!

        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by JonB
        #11

        @Christian-Ehrlicher
        I, and you, have repeatedly advised @n-2204 to change from the old macros to the new style, and provided the necessary links (e.g. https://forum.qt.io/topic/126193/spinbox-input-add-rows, I think we posted 4 times there to this effect). Precisely because the user keeps getting the connections wrong. It seems the user is not interested in making the effort to change their ways, and prefers to make the same mistakes and keep posting for others to sort out....

        1 Reply Last reply
        3
        • N Offline
          N Offline
          n-2204
          wrote on last edited by
          #12
          connect(ui.tableView->model(), &QAbstractItemModel::rowsInserted, this,
          &tool::changedvalue);
          

          but signal/slot should work for both the ways
          and one thing is there is change in column 1 row values and @VRonin you told to use signal rowinserted() ?

          VRoninV 1 Reply Last reply
          0
          • N n-2204
            connect(ui.tableView->model(), &QAbstractItemModel::rowsInserted, this,
            &tool::changedvalue);
            

            but signal/slot should work for both the ways
            and one thing is there is change in column 1 row values and @VRonin you told to use signal rowinserted() ?

            VRoninV Offline
            VRoninV Offline
            VRonin
            wrote on last edited by
            #13

            but signal/slot should work for both the ways

            It does but in case you make a mistake the new syntax lets you know straight away when you try to compile and it's not just a warning in the console while the program runs.
            Also the new connection is faster

            there is change in column 1 row values and @VRonin you told to use signal rowinserted() ?

            In that case you would use the conveniently named dataChanged signal

            void tool::changedvalue()

            please do no rebuild all the widgets everytime something changes. setIndexWidget is already super inefficient, if you keep recreating them your program will probably stutter a lot

            "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
            3
            • N Offline
              N Offline
              n-2204
              wrote on last edited by n-2204
              #14

              So when i am passing my values in a Qstring that time its coming in combobox but same when i try using table1 column1 rows value that time only last row value is adding in Combobox values looks like all values not appending
              Where need to make changes?

              connect(ui.tableView->model(), &QAbstractItemModel::dataChanged, this,
                        &Gearcycle_model::changedvalue);
              
              void tool::changedvalue() {
              QAbstractItemModel* table1 = ui.tableView->model();
              QAbstractItemModel* table2 = ui.tableView_2->model();
              for (int i = 0, maxI = table2->rowCount();i <= maxI;++i)//combobox in table2 col1
              {
                  for (int r = 0, maxI = table1->rowCount();r < maxI;++r)//getvalue fromtable1
                  {
                      QComboBox* combo = new QComboBox();
                      //QString list1[10] = { table1->data(table1->index(r, 0)).toString() };//store value in list
                      QString list1[4] = { "input 1","input 2","input3","input 4" };
                      qDebug() << "table index" << r;
                      for (int j = 0; j < 3; j++)
                      {
                          combo->addItem(list1[j]);
                          qDebug() << "combox values" << list1[j];//pass list to combobox
                          qDebug() << "list j=" << j;
                      }
                      ui.tableView_2->setIndexWidget(ui.tableView_2->model()->index(i, 1), combo);
                      qDebug() << "row value i=" << i;
                  }
              }
              }
              
              VRoninV N 2 Replies Last reply
              0
              • N n-2204

                So when i am passing my values in a Qstring that time its coming in combobox but same when i try using table1 column1 rows value that time only last row value is adding in Combobox values looks like all values not appending
                Where need to make changes?

                connect(ui.tableView->model(), &QAbstractItemModel::dataChanged, this,
                          &Gearcycle_model::changedvalue);
                
                void tool::changedvalue() {
                QAbstractItemModel* table1 = ui.tableView->model();
                QAbstractItemModel* table2 = ui.tableView_2->model();
                for (int i = 0, maxI = table2->rowCount();i <= maxI;++i)//combobox in table2 col1
                {
                    for (int r = 0, maxI = table1->rowCount();r < maxI;++r)//getvalue fromtable1
                    {
                        QComboBox* combo = new QComboBox();
                        //QString list1[10] = { table1->data(table1->index(r, 0)).toString() };//store value in list
                        QString list1[4] = { "input 1","input 2","input3","input 4" };
                        qDebug() << "table index" << r;
                        for (int j = 0; j < 3; j++)
                        {
                            combo->addItem(list1[j]);
                            qDebug() << "combox values" << list1[j];//pass list to combobox
                            qDebug() << "list j=" << j;
                        }
                        ui.tableView_2->setIndexWidget(ui.tableView_2->model()->index(i, 1), combo);
                        qDebug() << "row value i=" << i;
                    }
                }
                }
                
                VRoninV Offline
                VRoninV Offline
                VRonin
                wrote on last edited by
                #15

                @n-2204 said in Combobox in Qtableview:

                Where need to make changes?

                Read your code. The loops are wrong, this is basic C++

                "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
                1
                • N n-2204

                  So when i am passing my values in a Qstring that time its coming in combobox but same when i try using table1 column1 rows value that time only last row value is adding in Combobox values looks like all values not appending
                  Where need to make changes?

                  connect(ui.tableView->model(), &QAbstractItemModel::dataChanged, this,
                            &Gearcycle_model::changedvalue);
                  
                  void tool::changedvalue() {
                  QAbstractItemModel* table1 = ui.tableView->model();
                  QAbstractItemModel* table2 = ui.tableView_2->model();
                  for (int i = 0, maxI = table2->rowCount();i <= maxI;++i)//combobox in table2 col1
                  {
                      for (int r = 0, maxI = table1->rowCount();r < maxI;++r)//getvalue fromtable1
                      {
                          QComboBox* combo = new QComboBox();
                          //QString list1[10] = { table1->data(table1->index(r, 0)).toString() };//store value in list
                          QString list1[4] = { "input 1","input 2","input3","input 4" };
                          qDebug() << "table index" << r;
                          for (int j = 0; j < 3; j++)
                          {
                              combo->addItem(list1[j]);
                              qDebug() << "combox values" << list1[j];//pass list to combobox
                              qDebug() << "list j=" << j;
                          }
                          ui.tableView_2->setIndexWidget(ui.tableView_2->model()->index(i, 1), combo);
                          qDebug() << "row value i=" << i;
                      }
                  }
                  }
                  
                  N Offline
                  N Offline
                  n-2204
                  wrote on last edited by n-2204
                  #16

                  @n-2204 said in Combobox in Qtableview:

                  So when i am passing my values in a Qstring that time its coming in combobox but same when i try using table1 column1 rows value that time only last row value is adding in Combobox values looks like all values not appending
                  Where need to make changes?

                  connect(ui.tableView->model(), &QAbstractItemModel::dataChanged, this,
                            &Gearcycle_model::changedvalue);
                  
                  void tool::changedvalue() {
                  QAbstractItemModel* table1 = ui.tableView->model();
                  QAbstractItemModel* table2 = ui.tableView_2->model();
                  for (int i = 0, maxI = table2->rowCount();i <= maxI;++i)//combobox in table2 col1
                  {
                      for (int r = 0, maxI = table1->rowCount();r < maxI;++r)//getvalue fromtable1
                      {
                          QComboBox* combo = new QComboBox();
                          //QString list1[10] = { table1->data(table1->index(r, 0)).toString() };//store value in list
                  

                  when passing this that time only last row value is coming in combobox

                          QString list1[4] = { "input 1","input 2","input3","input 4" };
                  

                  this is working when i am passing QString list1[4] = { "input 1","input 2","input3","input 4" }; in combobox

                          for (int j = 0; j < 3; j++)
                          {
                              combo->addItem(list1[j]);
                              qDebug() << "combox values" << list1[j];//pass list to combobox
                              qDebug() << "list j=" << j;
                          }
                          ui.tableView_2->setIndexWidget(ui.tableView_2->model()->index(i, 1), combo);
                          qDebug() << "row value i=" << i;
                      }
                  }
                  }
                  

                  yes, looks like some small change will be needed during addItem in combobox

                  1 Reply Last reply
                  0
                  • VRoninV Offline
                    VRoninV Offline
                    VRonin
                    wrote on last edited by VRonin
                    #17

                    Look at the loops of i and r. think about what they are doing, ask yourself when you want to create and populate a combo, inside which loop?

                    "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
                    1
                    • N Offline
                      N Offline
                      n-2204
                      wrote on last edited by n-2204
                      #18

                      ya it works thankyou.

                      void tool::rowvalue1() {
                      QAbstractItemModel* table1 = ui.tableView->model();
                      QAbstractItemModel* table2 = ui.tableView_2->model();
                      for (int i = 0, maxI = table2->rowCount();i < maxI;++i)//combobox in table2 col1
                      {
                           QComboBox* combo = new QComboBox();
                            combo->setDuplicatesEnabled(false);
                        for (int r = 0, maxI = table1->rowCount();r < maxI;++r)//getvalue fromtable1
                            {
                               QString list1[10] = { table1->data(table1->index(r, 0)).toString() };//store value in list
                             for (int j = 0; j < 1; ++j)
                              {
                      

                      --using uniqueSet trying to add only unique values(no duplicate values) in Combobox but its not working is this correct way ? or any other way to do this ?

                                  QSet<QString> uniqueSet;
                                   if (!uniqueSet.contains(list1[j]))//add only unique values in combobox
                                   {
                                      uniqueSet.insert(list1[j]);
                                      combo->addItem(list1[j]);  //add list to combobox  
                                      qDebug() << " values " << list1[j];
                                  }
                              }
                              ui.tableView_2->setIndexWidget(table2->index(i, 1), combo);
                          }
                        }
                      }
                      
                      1 Reply Last reply
                      0
                      • VRoninV Offline
                        VRoninV Offline
                        VRonin
                        wrote on last edited by
                        #19

                        @n-2204 said in Combobox in Qtableview:

                        for (int j = 0; j < 1; ++j)

                        What?!

                        "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
                        2
                        • N Offline
                          N Offline
                          n-2204
                          wrote on last edited by n-2204
                          #20

                          no its 10
                          j<10
                          using uniqueSet trying to add only unique values(no duplicate values) in Combobox but its not working is this correct way ? or any other way to do this ?

                          JonBJ 1 Reply Last reply
                          0
                          • VRoninV Offline
                            VRoninV Offline
                            VRonin
                            wrote on last edited by
                            #21

                            My feeling is that you have no idea what your code does, you are just copy-pasting stuff around and hoping that it does something.
                            Once again: read your code, run it step-by-step. This has nothing to do with Qt, it's just about loops

                            "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
                            1
                            • N Offline
                              N Offline
                              n-2204
                              wrote on last edited by
                              #22

                              thanks for your answers
                              9f7df07c-9f26-4a5b-826b-00d285364dcb-image.png
                              but what i shared i working code
                              and now i asked -
                              using uniqueSet trying to add only unique values(no duplicate values) in Combobox but this way not working is this correct way ? or any other way to do this ?

                              this it might be very simple for you or you are expert but i am new C++ and Qt so i am having so many doubts may be silly.
                              Thanks

                              1 Reply Last reply
                              0
                              • N n-2204

                                no its 10
                                j<10
                                using uniqueSet trying to add only unique values(no duplicate values) in Combobox but its not working is this correct way ? or any other way to do this ?

                                JonBJ Offline
                                JonBJ Offline
                                JonB
                                wrote on last edited by JonB
                                #23

                                @n-2204 said in Combobox in Qtableview:

                                no its 10
                                j<10

                                No, the code you pasted reads:

                                 for (int j = 0; j < 1; ++j)
                                

                                That's 1, not 10. Or are you saying you want help to fix your code but you don't paste the actual code you want help with?

                                using uniqueSet trying to add only unique values(no duplicate values) in Combobox but this way not working

                                If your pasted code is to be believed, you seem to declare QSet<QString> uniqueSet; inside the j loop.

                                            QSet<QString> uniqueSet;
                                             if (!uniqueSet.contains(list1[j]))//add only unique values in combobox
                                

                                This will always be true. uniqueSet is always empty.

                                1 Reply Last reply
                                1
                                • mrjjM Offline
                                  mrjjM Offline
                                  mrjj
                                  Lifetime Qt Champion
                                  wrote on last edited by mrjj
                                  #24

                                  Hi

                                  • any other way ?

                                  Well your idea with QSet<QString> uniqueSet; was fine, but the logic/location was not right
                                  and i think QStringList might be easier.

                                  so this would do it. ( i assume you want a combo on each row in table 2 with same non-dub values in the combo)

                                     QAbstractItemModel *table1 = ui->tableView->model();
                                      QAbstractItemModel *table2 = ui->tableView_2->model();
                                      QStringList guesslist;
                                      for (int r = 0, maxI = table1->rowCount(); r < maxI; ++r) { //for all value rows
                                          guesslist.append( table1->data(table1->index(r, 0)).toString() );//store value in stringlist
                                      }
                                      guesslist.removeDuplicates(); // strip dubs
                                      for (int i = 0, maxI = table2->rowCount(); i < maxI; ++i) { //for all rows
                                          QComboBox *combo = new QComboBox(); // make combo
                                          combo->addItems(guesslist);  //add list to combobox
                                          ui->tableView_2->setIndexWidget(table2->index(i, 1), combo);// add combo
                                      }
                                  

                                  alt text

                                  But a word of warning. If you have many rows then setIndexWidget can become quite heavy for
                                  smaller devices and the app might lag. The cure is using a delegate as fully shown here ( thx VRonin :)

                                  https://forum.qt.io/topic/125906/qtableview-combobox-in-columns/10

                                  This also has the benefit that you don't need to copy anything around. its using the values directly. always updated.

                                  1 Reply Last reply
                                  2
                                  • N Offline
                                    N Offline
                                    n-2204
                                    wrote on last edited by
                                    #25

                                    QStringList might be easier
                                    guesslist.removeDuplicates(); // strip dubs

                                     Ok Thanks!! but still looks like empty row value is coming in Combobox
                                    

                                    if you have many rows then setIndexWidget can become quite heavy for
                                    smaller devices and the app might lag

                                    I am having 6-7 rows in my table
                                    

                                    I'm not using delegate as I need to read index, selection and apply some condition based on Combobox values in other columns ...,for some further req.

                                    Thanks

                                    mrjjM 1 Reply Last reply
                                    0
                                    • N n-2204

                                      QStringList might be easier
                                      guesslist.removeDuplicates(); // strip dubs

                                       Ok Thanks!! but still looks like empty row value is coming in Combobox
                                      

                                      if you have many rows then setIndexWidget can become quite heavy for
                                      smaller devices and the app might lag

                                      I am having 6-7 rows in my table
                                      

                                      I'm not using delegate as I need to read index, selection and apply some condition based on Combobox values in other columns ...,for some further req.

                                      Thanks

                                      mrjjM Offline
                                      mrjjM Offline
                                      mrjj
                                      Lifetime Qt Champion
                                      wrote on last edited by
                                      #26

                                      @n-2204

                                      Hi

                                      • Ok Thanks!! but still looks like empty row value is coming in Combobox

                                      Yes we add empty ones too but you can just dont do that.

                                      for (int r = 0, maxI = table1->rowCount(); r < maxI; ++r) { //for all value rows
                                         QString str = table1->data(table1->index(r, 0)).toString();
                                          if ( ! str.IsEmpty() ) 
                                           guesslist.append( str );//store value in stringlist
                                          }
                                      

                                      https://doc.qt.io/qt-5/qstring.html#isEmpty

                                      1 Reply Last reply
                                      0
                                      • VRoninV Offline
                                        VRoninV Offline
                                        VRonin
                                        wrote on last edited by VRonin
                                        #27

                                        @mrjj said in Combobox in Qtableview:

                                        for (int i = 0, maxI = table2->rowCount(); i < maxI; ++i) { //for all rows
                                        QComboBox *combo = new QComboBox(); // make combo
                                        combo->addItems(guesslist); //add list to combobox
                                        ui->tableView_2->setIndexWidget(table2->index(i, 1), combo);// add combo
                                        }

                                        Slight tweak to avoid recreating the combobox every time:

                                        for (int i = 0, maxI = table2->rowCount(); i < maxI; ++i) { //for all rows
                                        	const QModelIndex idx = table2->index(i, 1);
                                        	QComboBox *combo = qobject_cast<QComboBox*>(ui->tableView_2->indexWidget(idx));
                                        	if(!combo){
                                        		combo = new QComboBox(); // make combo  
                                        		ui->tableView_2->setIndexWidget(idx , combo);// add combo
                                        	}
                                        	combo->model()->removeRows(0,combo->count(),combo->rootModelIndex());
                                        	combo->addItems(guesslist);  //add list to combobox
                                        }
                                        

                                        @n-2204 said in Combobox in Qtableview:

                                        I'm not using delegate as I need to read index, selection and apply some condition based on Combobox values in other columns

                                        You can do that with delegates too. Probably even easier.

                                        "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
                                        1
                                        • N Offline
                                          N Offline
                                          n-2204
                                          wrote on last edited by n-2204
                                          #28

                                          @VRonin @mrjj
                                          1.
                                          Actually when I'm using both the ways to add values in Combobox
                                          one thing happening ,if I added some values in column0 table1 then select in combobox and again adding values in table1 Column0 that time combobox selection go away

                                          I am using dataChanged() signal
                                          connect(ui.tableView->model(), &QAbstractItemModel::dataChanged, this,
                                          &tool::rowvalue1);
                                          Is it because of this signal ? how can i prevent this ??

                                          1. As I'm using SLOT::rowvalue1() to add combobox in Qtableview
                                            now how can i take index() of combobox as there is SIGNAL::QComboBox::currentIndexChanged, , so again I need to write SLOT for index
                                            void tool::IndexChanged(int index)
                                            {
                                            combo->setCurrentIndex(combo->currentIndex());
                                            //but combo will be inaccessible here ??
                                            }
                                            connect(combo, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
                                            &tool::IndexChanged);
                                            Is this correct way ?
                                          VRoninV 1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved