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. Changes in table with combo boxes
Forum Updated to NodeBB v4.3 + New Features

Changes in table with combo boxes

Scheduled Pinned Locked Moved Solved General and Desktop
23 Posts 3 Posters 8.4k Views 2 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.
  • VRoninV Offline
    VRoninV Offline
    VRonin
    wrote on last edited by VRonin
    #12

    You probably need to tweak the setEditorData method. qobject_cast<QComboBox*>(editor)->setCurrentText(index.model()->data(index, Qt::EditRole).toString()); assumes the index.data(Qt::EditRole).toString() is already in the combo box list which might not be the case. change it to:

    {
    auto comboEditor =qobject_cast<QComboBox*>(editor);
    Q_ASSERT(comboEditor);
    const QString& textToFind = index.data(Qt::EditRole).toString();
    int itemIdx = comboEditor->findText(textToFind);
    if(itemIdx<0){
    comboEditor->addItem(textToFind);
    itemIdx  = comboEditor->findText(textToFind);
    }
    Q_ASSERT(itemIdx>=0);
    comboEditor->setCurrentIndex(itemIdx);
    }
    

    EDIT fixed compile fail and wrong Q_ASSERT condition

    "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

    K 1 Reply Last reply
    1
    • VRoninV VRonin

      You probably need to tweak the setEditorData method. qobject_cast<QComboBox*>(editor)->setCurrentText(index.model()->data(index, Qt::EditRole).toString()); assumes the index.data(Qt::EditRole).toString() is already in the combo box list which might not be the case. change it to:

      {
      auto comboEditor =qobject_cast<QComboBox*>(editor);
      Q_ASSERT(comboEditor);
      const QString& textToFind = index.data(Qt::EditRole).toString();
      int itemIdx = comboEditor->findText(textToFind);
      if(itemIdx<0){
      comboEditor->addItem(textToFind);
      itemIdx  = comboEditor->findText(textToFind);
      }
      Q_ASSERT(itemIdx>=0);
      comboEditor->setCurrentIndex(itemIdx);
      }
      

      EDIT fixed compile fail and wrong Q_ASSERT condition

      K Offline
      K Offline
      koahnig
      wrote on last edited by
      #13

      @VRonin

      Thanks for update.

      Unfortunately, the tweaking does not work. setEditorData is a const method. Therefore, the compiler complains about addItem use.

      Just for completeness. The main tests on my side are on Win 10 and Qt 5.4.2 with MinGW. I have checked it also with Qt 5.9.1 for MinGW. The use of proxy model is always an issue. However, the behaviour is different for both versions.
      The major issue is for Qt 5.4.2 that ComboBox entries held are 2 text plus a varying number blank lines at top.
      For Qt 5.9.1 it is the opposite. Apparently, two blank lines at the end and varying number of entries at top, but also some are missing.
      I am giving up for testing at the time, since my knowledge is not sound enough, yet. Also is the functionality with by-passing of proxy model sufficient for my current use case.

      However, it is time give the following statements.
      Even though I am "complaining" about some deficiencies in your code, I see it more as a feedback in case you need some input.
      Your assistance helped significantly improving my speed in getting a workable solution.

      A huge thanks for turbo-teaching!!

      Vote the answer(s) that helped you to solve your issue(s)

      VRoninV 1 Reply Last reply
      0
      • K koahnig

        @VRonin

        Thanks for update.

        Unfortunately, the tweaking does not work. setEditorData is a const method. Therefore, the compiler complains about addItem use.

        Just for completeness. The main tests on my side are on Win 10 and Qt 5.4.2 with MinGW. I have checked it also with Qt 5.9.1 for MinGW. The use of proxy model is always an issue. However, the behaviour is different for both versions.
        The major issue is for Qt 5.4.2 that ComboBox entries held are 2 text plus a varying number blank lines at top.
        For Qt 5.9.1 it is the opposite. Apparently, two blank lines at the end and varying number of entries at top, but also some are missing.
        I am giving up for testing at the time, since my knowledge is not sound enough, yet. Also is the functionality with by-passing of proxy model sufficient for my current use case.

        However, it is time give the following statements.
        Even though I am "complaining" about some deficiencies in your code, I see it more as a feedback in case you need some input.
        Your assistance helped significantly improving my speed in getting a workable solution.

        A huge thanks for turbo-teaching!!

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

        @koahnig said in Changes in table with combo boxes:

        the compiler complains about addItem use.

        you can still copy the entire content of additem in that block or exploit the combo and call comboEditor->addItem instead. also, probably it's worth preventing empty (or even whitespace only) strings to be added

        The blank lines are weird. you could check what is going on by inquiring m_comboProxy->rowCount()

        "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

        K VRoninV 2 Replies Last reply
        0
        • VRoninV VRonin

          @koahnig said in Changes in table with combo boxes:

          the compiler complains about addItem use.

          you can still copy the entire content of additem in that block or exploit the combo and call comboEditor->addItem instead. also, probably it's worth preventing empty (or even whitespace only) strings to be added

          The blank lines are weird. you could check what is going on by inquiring m_comboProxy->rowCount()

          K Offline
          K Offline
          koahnig
          wrote on last edited by
          #15

          @VRonin

          Code of setEditorData

          {
              auto comboEditor =qobject_cast<QComboBox*>(editor);
              Q_ASSERT(comboEditor);
              const QString& textToFind = index.data(Qt::EditRole).toString();
              int itemIdx = comboEditor->findText(textToFind);
              if(itemIdx<0){
                  comboEditor->addItem(textToFind);
                  itemIdx  = comboEditor->findText(textToFind);
                  qDebug() << "addItem " << textToFind << " " << itemIdx << " " << m_comboProxy->rowCount() << " " << m_comboProxy->columnCount();
              }
              Q_ASSERT ( itemIdx >= 0 );
              comboEditor->setCurrentIndex(itemIdx);
              qDebug() << "in combo box " << comboEditor->currentText() << " " << itemIdx << " " << m_comboProxy->rowCount() << " " << m_comboProxy->columnCount();;
          }
          

          Double click on 4, 2
          Typing "Testing" <enter>
          Double click on 6, 2
          Typing "erf"
          Double click 8, 2
          Typing "Zufall"

          output window:

          Starting r:\build-AnotherComboBoxTest-Desktop_Qt_5_9_1_MinGW_32bit-Debug\debug\AnotherComboBoxTest.exe...
          addItem  ""   0   2   1
          in combo box  ""   0   2   1
          in combo box  "testing"   2   3   1
          in combo box  "testing"   2   3   1
          in combo box  ""   0   3   1
          in combo box  "erf"   1   4   1
          in combo box  "erf"   1   4   1
          in combo box  ""   0   4   1
          in combo box  ""   0   5   1
          in combo box  ""   0   5   1
          

          That's the outcome
          0_1504276956694_b09f76a4-5adb-4721-b3d9-57667fced486-image.png

          Vote the answer(s) that helped you to solve your issue(s)

          1 Reply Last reply
          0
          • VRoninV VRonin

            @koahnig said in Changes in table with combo boxes:

            the compiler complains about addItem use.

            you can still copy the entire content of additem in that block or exploit the combo and call comboEditor->addItem instead. also, probably it's worth preventing empty (or even whitespace only) strings to be added

            The blank lines are weird. you could check what is going on by inquiring m_comboProxy->rowCount()

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

            Yep, that's what I meant with:

            @VRonin said in Changes in table with combo boxes:

            also, probably it's worth preventing empty (or even whitespace only) strings

            void ComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
            {
                if (index.data(Qt::EditRole).isNull())
                    qobject_cast<QComboBox*>(editor)->setCurrentIndex(-1);
                else
            {
                auto comboEditor =qobject_cast<QComboBox*>(editor);
                Q_ASSERT(comboEditor);
                const QString& textToFind = index.data(Qt::EditRole).toString();
                //make sure you are not just searching whitespace
            const QRegularExpression realTextRegExp("\S+");
            if(!realTextRegExp.match(textToFind).hasMatch()){
            comboEditor->setCurrentIndex(-1);
            return;
            }
            int itemIdx = comboEditor->findText(textToFind);
                if(itemIdx<0){
                    comboEditor->addItem(textToFind);
                    itemIdx  = comboEditor->findText(textToFind);
                    qDebug() << "addItem " << textToFind << " " << itemIdx << " " << m_comboProxy->rowCount() << " " << m_comboProxy->columnCount();
                }
                Q_ASSERT ( itemIdx >= 0 );
                comboEditor->setCurrentIndex(itemIdx);
                qDebug() << "in combo box " << comboEditor->currentText() << " " << itemIdx << " " << m_comboProxy->rowCount() << " " << m_comboProxy->columnCount();
            }
            }
            

            "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

            K 1 Reply Last reply
            1
            • VRoninV VRonin

              Yep, that's what I meant with:

              @VRonin said in Changes in table with combo boxes:

              also, probably it's worth preventing empty (or even whitespace only) strings

              void ComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
              {
                  if (index.data(Qt::EditRole).isNull())
                      qobject_cast<QComboBox*>(editor)->setCurrentIndex(-1);
                  else
              {
                  auto comboEditor =qobject_cast<QComboBox*>(editor);
                  Q_ASSERT(comboEditor);
                  const QString& textToFind = index.data(Qt::EditRole).toString();
                  //make sure you are not just searching whitespace
              const QRegularExpression realTextRegExp("\S+");
              if(!realTextRegExp.match(textToFind).hasMatch()){
              comboEditor->setCurrentIndex(-1);
              return;
              }
              int itemIdx = comboEditor->findText(textToFind);
                  if(itemIdx<0){
                      comboEditor->addItem(textToFind);
                      itemIdx  = comboEditor->findText(textToFind);
                      qDebug() << "addItem " << textToFind << " " << itemIdx << " " << m_comboProxy->rowCount() << " " << m_comboProxy->columnCount();
                  }
                  Q_ASSERT ( itemIdx >= 0 );
                  comboEditor->setCurrentIndex(itemIdx);
                  qDebug() << "in combo box " << comboEditor->currentText() << " " << itemIdx << " " << m_comboProxy->rowCount() << " " << m_comboProxy->columnCount();
              }
              }
              
              K Offline
              K Offline
              koahnig
              wrote on last edited by
              #17

              @VRonin

              I am sorry to correct, but it doesn't help either.

              The problem is with the index coming into setEditorData

              Here is my latest code:

              void ComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
              {
                  if (index.data(Qt::EditRole).isNull())
                      qobject_cast<QComboBox*>(editor)->setCurrentIndex(-1);
                  else
                  {
                      auto comboEditor =qobject_cast<QComboBox*>(editor);
                      Q_ASSERT(comboEditor);
                      qDebug() << " index " << index;
                      const QString& textToFind = index.data(Qt::EditRole).toString();
                      qDebug() << "textToFind before reg exp " << textToFind;
                      //make sure you are not just searching whitespace
                      const QRegularExpression realTextRegExp("\\S+");
                      if( ! realTextRegExp.match(textToFind).hasMatch()){
                          qDebug() << "textToFind " << textToFind;
                          comboEditor->setCurrentIndex(-1);
                          return;
                      }
                      int itemIdx = comboEditor->findText(textToFind);
                      if(itemIdx<0){
                          comboEditor->addItem(textToFind);
                          itemIdx  = comboEditor->findText(textToFind);
                          qDebug() << "addItem " << textToFind << " " << itemIdx << " " << m_comboProxy->rowCount() << " " << m_comboProxy->columnCount();
                      }
                      Q_ASSERT ( itemIdx >= 0 );
                      comboEditor->setCurrentIndex(itemIdx);
                      qDebug() << "in combo box " << comboEditor->currentText() << " " << itemIdx << " " << m_comboProxy->rowCount() << " " << m_comboProxy->columnCount();
                  }
              }
              

              That is the latest output:

              Starting r:\build-AnotherComboBoxTest-Desktop_Qt_5_9_1_MinGW_32bit-Debug\debug\AnotherComboBoxTest.exe...
              no delegate found
              addItem  "test 1 1"   E:\Source\AnotherComboBoxTest\MyTableWidget.cpp 28
              addItem  "test 1 2"   E:\Source\AnotherComboBoxTest\MyTableWidget.cpp 28
               index  QModelIndex(3,1,0x0,QTableModel(0x175fb6a8))
              textToFind before reg exp  "testing"
              in combo box  "testing"   1   2   1
               index  QModelIndex(3,1,0x0,QTableModel(0x175fb6a8))
              textToFind before reg exp  "testing"
              in combo box  "testing"   1   2   1
               index  QModelIndex(5,1,0x0,QTableModel(0x175fb6a8))
              textToFind before reg exp  "erf"
              in combo box  "erf"   0   3   1
               index  QModelIndex(5,1,0x0,QTableModel(0x175fb6a8))
              textToFind before reg exp  "erf"
              in combo box  "erf"   0   3   1
               index  QModelIndex(7,1,0x0,QTableModel(0x175fb6a8))
              textToFind before reg exp  ""
              textToFind  ""
               index  QModelIndex(7,1,0x0,QTableModel(0x175fb6a8))
              textToFind before reg exp  ""
              textToFind  ""
              

              In additiion the update problems there are also the initial input for this test "test 1 1" not covered anymore after some input directly to the table.

              Vote the answer(s) that helped you to solve your issue(s)

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

                Isn't that the correct output? what were you expecting?

                "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

                K 1 Reply Last reply
                0
                • VRoninV VRonin

                  Isn't that the correct output? what were you expecting?

                  K Offline
                  K Offline
                  koahnig
                  wrote on last edited by
                  #19

                  @VRonin

                  Nope, I did the same as with the previous tests. Only lower case letters this time. The input was:

                  • Double click on 4, 2
                  • Typing "testing" <enter>
                  • Double click on 6, 2
                  • Typing "erf" <enter>
                  • Double click 8, 2
                  • Typing "zufall" <enter>

                  Vote the answer(s) that helped you to solve your issue(s)

                  1 Reply Last reply
                  0
                  • K Offline
                    K Offline
                    koahnig
                    wrote on last edited by
                    #20

                    We are back to the start :(

                    #define USE_COMBO_PROXY
                    QWidget* ComboBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const
                    {
                        QComboBox* result = new QComboBox(parent);
                        result->setEditable( true );
                        result->setInsertPolicy( QComboBox::InsertAlphabetically );
                    
                    #ifdef USE_COMBO_PROXY
                    //    m_comboProxy->sort( 0 );
                        result->setModel(m_comboProxy);
                    #else
                        result->setModel(m_comboModel);
                    #endif
                    
                        return result;
                    }
                    

                    Commenting out m_comboProxy->sort( 0 ) or by-passing the whole proxy model do work correctly.

                    Vote the answer(s) that helped you to solve your issue(s)

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

                      Sorry but now I'm lost. could you describe what the expected output was?

                      "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
                      0
                      • VRoninV Offline
                        VRoninV Offline
                        VRonin
                        wrote on last edited by
                        #22

                        for anyone ending in this post from google, you should add m_comboProxy->setDynamicSortFilter(false); in the constructor of the 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

                        K 1 Reply Last reply
                        2
                        • VRoninV VRonin

                          for anyone ending in this post from google, you should add m_comboProxy->setDynamicSortFilter(false); in the constructor of the delegate

                          K Offline
                          K Offline
                          koahnig
                          wrote on last edited by
                          #23

                          @VRonin

                          Yes, this does the trick.
                          After introducing the line in the constructor the test example is working.

                          Once again, many thanks for your help.

                          Vote the answer(s) that helped you to solve your issue(s)

                          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