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. QComboBox value mapping

QComboBox value mapping

Scheduled Pinned Locked Moved Unsolved General and Desktop
16 Posts 5 Posters 3.5k Views
  • 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.
  • A Offline
    A Offline
    anuj nogja
    wrote on last edited by anuj nogja
    #1

    Hi All,
    There is a requiremnt in the project to create two comboBox (having same items) such that value selected in one comboBox should not appear in the dropdown of another combo box.
    For Example:
    ComboBox1- ComboBox2
    Item1 - Item1
    Item2 - Item2
    Item3 - Item3

    suppose if user select Item1 from ComboBox1 then Item1 should not appear in the dropdown of ComboBox2.

    Kindly suggest how this can be achieved...

    Regards,
    Anuj

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

      EDIT: this code is wrong, look below

      QStringListModel* comboModel=new QStringListModel(QStringList() << "Item1" << "Item2" << "Item3",this);
      QSortFilterProxyModel* comboFilter = new QSortFilterProxyModel(this);
      comboFilter->setSourceModel(comboModel);
      combo1->setModel(comboModel);
      combo2->setModel(comboFilter);
      connect(combo1, QOverload<const QString&>::of(&QComboBox::currentIndexChanged),comboFilter,[comboFilter](const QString &text)->void{comboFilter->setFilterRegExp("^(?!"+text+".*)$");});
      

      "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

      A JonBJ 2 Replies Last reply
      3
      • VRoninV VRonin

        EDIT: this code is wrong, look below

        QStringListModel* comboModel=new QStringListModel(QStringList() << "Item1" << "Item2" << "Item3",this);
        QSortFilterProxyModel* comboFilter = new QSortFilterProxyModel(this);
        comboFilter->setSourceModel(comboModel);
        combo1->setModel(comboModel);
        combo2->setModel(comboFilter);
        connect(combo1, QOverload<const QString&>::of(&QComboBox::currentIndexChanged),comboFilter,[comboFilter](const QString &text)->void{comboFilter->setFilterRegExp("^(?!"+text+".*)$");});
        
        A Offline
        A Offline
        anuj nogja
        wrote on last edited by
        #3

        @VRonin Hi,

        Getting an error "no matching call to "QOverload<const QString&>::of(&QComboBox::currentIndexChanged)".

        Regards,
        Anuj

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

          That's a straight copy-paste from the Qt docs. What version of Qt are you using?
          Make sure you have CONFIG += c++11 in your .pro file and re-run qmake

          "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 VRonin

            EDIT: this code is wrong, look below

            QStringListModel* comboModel=new QStringListModel(QStringList() << "Item1" << "Item2" << "Item3",this);
            QSortFilterProxyModel* comboFilter = new QSortFilterProxyModel(this);
            comboFilter->setSourceModel(comboModel);
            combo1->setModel(comboModel);
            combo2->setModel(comboFilter);
            connect(combo1, QOverload<const QString&>::of(&QComboBox::currentIndexChanged),comboFilter,[comboFilter](const QString &text)->void{comboFilter->setFilterRegExp("^(?!"+text+".*)$");});
            
            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by JonB
            #5

            @VRonin said in QComboBox value mapping:

            "^(?!"+text+".*)$"

            [Not that this has anything to do with the OP's current problem, but...]

            What does that monstrous reg exp mean (the ?!)? And my first thought is that doesn't the arbitrary text content need reg-exp protection for funny chars?

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @JonB https://regex101.com is your friend when dealing with regular expression.

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

              JonBJ 1 Reply Last reply
              1
              • SGaistS SGaist

                @JonB https://regex101.com is your friend when dealing with regular expression.

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

                @SGaist
                OK, so (?!...) is "negative lookahead". I think you are filtering out items starting withtext (why only starting with, I don't know). But the text might happen to contain reg ex special chars, and you're not escaping them? I'm just trying to understand....

                1 Reply Last reply
                2
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  In the case at hand, if text happened to contain such special characters, then yes it wouldn't be handle properly but it's then the responsibility of the author to handle that case if such an expression could be listed in the first combobox.

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

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

                    To avoid the problem @JonB correctly highlighted:

                    • create this class in a header file
                    class NegativeSortFilterProxyModel : public QSortFilterProxyModel{
                    Q_OBJECT
                    Q_DISABLE_COPY(NegativeSortFilterProxyModel)
                    public:
                    explicit NegativeSortFilterProxyModel(QObject* parent = Q_NULLPTR) : QSortFilterProxyModel(parent){}
                    protected:
                    bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const Q_DECL_OVERRIDE{
                    return !QSortFilterProxyModel::filterAcceptsRow(source_row,source_parent);
                    }
                    };
                    
                    • in the snippet above replace QSortFilterProxyModel with NegativeSortFilterProxyModel
                    • replace "^(?!"+text+".*)$" with '^'+QRegExp::escape(text)+'$'

                    "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
                    • SGaistS SGaist

                      In the case at hand, if text happened to contain such special characters, then yes it wouldn't be handle properly but it's then the responsibility of the author to handle that case if such an expression could be listed in the first combobox.

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

                      @SGaist said in QComboBox value mapping:

                      In the case at hand, if text happened to contain such special characters, then yes it wouldn't be handle properly but it's then the responsibility of the author to handle that case if such an expression could be listed in the first combobox.

                      OK, that clarifies, it was just that I was trying to confirm my understanding.

                      (I do not mean to be picky, or get into an argument. I understand this was example code now, and this is not a huge issue. I totally respect your excellent answers. But I do not agree that this should be written as "the responsibility of the author to handle that case if such an expression could be listed in the first combobox". Combobox could contain whatever. Your code --- given that it's picking up whatever happens to be in the other combo box to remove from this one --- should be responsible for whatever the Qt/C++/library is for going QRegExp(text)::EscapeProtectChars() instead of just passing text. IMHO.)

                      @VRonin

                      replace "^(?!"+text+".*)$" with '^'+text+'$'

                      Although your suggestion makes the reg exp a bit easier to understand, I don't see that it "To avoid the problem @JonB correctly highlighted" (if you mean about text), in that text is still inserted into a reg exp without escape/protection.

                      As I say, I don't mean to be picky/rude/disrespectful, I'm just trying to verify my understanding.

                      VRoninV 1 Reply Last reply
                      2
                      • JonBJ JonB

                        @SGaist said in QComboBox value mapping:

                        In the case at hand, if text happened to contain such special characters, then yes it wouldn't be handle properly but it's then the responsibility of the author to handle that case if such an expression could be listed in the first combobox.

                        OK, that clarifies, it was just that I was trying to confirm my understanding.

                        (I do not mean to be picky, or get into an argument. I understand this was example code now, and this is not a huge issue. I totally respect your excellent answers. But I do not agree that this should be written as "the responsibility of the author to handle that case if such an expression could be listed in the first combobox". Combobox could contain whatever. Your code --- given that it's picking up whatever happens to be in the other combo box to remove from this one --- should be responsible for whatever the Qt/C++/library is for going QRegExp(text)::EscapeProtectChars() instead of just passing text. IMHO.)

                        @VRonin

                        replace "^(?!"+text+".*)$" with '^'+text+'$'

                        Although your suggestion makes the reg exp a bit easier to understand, I don't see that it "To avoid the problem @JonB correctly highlighted" (if you mean about text), in that text is still inserted into a reg exp without escape/protection.

                        As I say, I don't mean to be picky/rude/disrespectful, I'm just trying to verify my understanding.

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

                        @JonB Sorry, I thought you were referring to another problem.
                        In my original implementation if you had Item1, Item2, ... , Item10 and select Item1, Item10 would disappear too.
                        i corrected the text above to do the regexp escaping too so now the NegativeSortFilterProxyModel solution should be general.

                        To put it all together:

                        class NegativeSortFilterProxyModel : public QSortFilterProxyModel{
                        Q_OBJECT
                        Q_DISABLE_COPY(NegativeSortFilterProxyModel)
                        public:
                        explicit NegativeSortFilterProxyModel(QObject* parent = Q_NULLPTR) : QSortFilterProxyModel(parent){}
                        protected:
                        bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const Q_DECL_OVERRIDE{
                        return !QSortFilterProxyModel::filterAcceptsRow(source_row,source_parent);
                        }
                        };
                        
                        QStringListModel* comboModel=new QStringListModel(QStringList() << "Item1" << "Item2" << "Item3",this);
                        NegativeSortFilterProxyModel* comboFilter = new NegativeSortFilterProxyModel(this);
                        comboFilter->setSourceModel(comboModel);
                        combo1->setModel(comboModel);
                        combo2->setModel(comboFilter);
                        connect(combo1, QOverload<const QString&>::of(&QComboBox::currentIndexChanged),comboFilter,[comboFilter](const QString &text)->void{comboFilter->setFilterRegExp('^'+QRegExp::escape(text)+'$');});
                        

                        "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

                        JonBJ A 2 Replies Last reply
                        4
                        • VRoninV VRonin

                          @JonB Sorry, I thought you were referring to another problem.
                          In my original implementation if you had Item1, Item2, ... , Item10 and select Item1, Item10 would disappear too.
                          i corrected the text above to do the regexp escaping too so now the NegativeSortFilterProxyModel solution should be general.

                          To put it all together:

                          class NegativeSortFilterProxyModel : public QSortFilterProxyModel{
                          Q_OBJECT
                          Q_DISABLE_COPY(NegativeSortFilterProxyModel)
                          public:
                          explicit NegativeSortFilterProxyModel(QObject* parent = Q_NULLPTR) : QSortFilterProxyModel(parent){}
                          protected:
                          bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const Q_DECL_OVERRIDE{
                          return !QSortFilterProxyModel::filterAcceptsRow(source_row,source_parent);
                          }
                          };
                          
                          QStringListModel* comboModel=new QStringListModel(QStringList() << "Item1" << "Item2" << "Item3",this);
                          NegativeSortFilterProxyModel* comboFilter = new NegativeSortFilterProxyModel(this);
                          comboFilter->setSourceModel(comboModel);
                          combo1->setModel(comboModel);
                          combo2->setModel(comboFilter);
                          connect(combo1, QOverload<const QString&>::of(&QComboBox::currentIndexChanged),comboFilter,[comboFilter](const QString &text)->void{comboFilter->setFilterRegExp('^'+QRegExp::escape(text)+'$');});
                          
                          JonBJ Offline
                          JonBJ Offline
                          JonB
                          wrote on last edited by JonB
                          #12

                          @VRonin said in QComboBox value mapping:

                          In my original implementation if you had Item1, Item2, ... , Item10 and select Item1, Item10 would disappear too.

                          Ah, yes indeed, I had asked/wondered why @SGaist's reg exp was a left-hand side match only, but nobody answered that, so I forgot about it. Again you have clarified my puzzlement by confirming it would have done a partial match by making yours a full match, so I am a happy understanding bunny now :)

                          1 Reply Last reply
                          0
                          • R Offline
                            R Offline
                            Rondog
                            wrote on last edited by Rondog
                            #13

                            If you are not dealing with a large number of items you could regenerate the contents of the second combobox excluding the selected item from the first combobox. Use the find option to make sure the same item is selected or active after rebuilding the list of combobox items (if the second combobox select happens to not match the first). You would iterate over the items in the first combobox and add them to the second excluding the one that is currently active.

                            If the are many items in the combobox you could use insert/delete (take) to add or remove items. It is a little more complicated to do this over the first method.

                            A 1 Reply Last reply
                            0
                            • R Rondog

                              If you are not dealing with a large number of items you could regenerate the contents of the second combobox excluding the selected item from the first combobox. Use the find option to make sure the same item is selected or active after rebuilding the list of combobox items (if the second combobox select happens to not match the first). You would iterate over the items in the first combobox and add them to the second excluding the one that is currently active.

                              If the are many items in the combobox you could use insert/delete (take) to add or remove items. It is a little more complicated to do this over the first method.

                              A Offline
                              A Offline
                              anuj nogja
                              wrote on last edited by
                              #14

                              @Rondog Hi
                              In the project, i have to deal with 8-9 items only. Can you please share the code of regenerating the content of second combobox based upon the selection of item in first combobox.

                              1 Reply Last reply
                              0
                              • VRoninV VRonin

                                @JonB Sorry, I thought you were referring to another problem.
                                In my original implementation if you had Item1, Item2, ... , Item10 and select Item1, Item10 would disappear too.
                                i corrected the text above to do the regexp escaping too so now the NegativeSortFilterProxyModel solution should be general.

                                To put it all together:

                                class NegativeSortFilterProxyModel : public QSortFilterProxyModel{
                                Q_OBJECT
                                Q_DISABLE_COPY(NegativeSortFilterProxyModel)
                                public:
                                explicit NegativeSortFilterProxyModel(QObject* parent = Q_NULLPTR) : QSortFilterProxyModel(parent){}
                                protected:
                                bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const Q_DECL_OVERRIDE{
                                return !QSortFilterProxyModel::filterAcceptsRow(source_row,source_parent);
                                }
                                };
                                
                                QStringListModel* comboModel=new QStringListModel(QStringList() << "Item1" << "Item2" << "Item3",this);
                                NegativeSortFilterProxyModel* comboFilter = new NegativeSortFilterProxyModel(this);
                                comboFilter->setSourceModel(comboModel);
                                combo1->setModel(comboModel);
                                combo2->setModel(comboFilter);
                                connect(combo1, QOverload<const QString&>::of(&QComboBox::currentIndexChanged),comboFilter,[comboFilter](const QString &text)->void{comboFilter->setFilterRegExp('^'+QRegExp::escape(text)+'$');});
                                
                                A Offline
                                A Offline
                                anuj nogja
                                wrote on last edited by
                                #15

                                @VRonin Its working fine but not able to select item1in combobox1. If i want to select item1 then first have to selwct some other item in combobox1 then only it allows to selwct item1.
                                Kindly suggest on how can item1 be selected.

                                Regards,
                                Anuj

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

                                  I can't reproduce, can you try this minimal example?

                                  #include <QApplication>
                                  #include <QSortFilterProxyModel>
                                  #include <QStringListModel>
                                  #include <QComboBox>
                                  #include <QHBoxLayout>
                                  class NegativeSortFilterProxyModel : public QSortFilterProxyModel{
                                      Q_DISABLE_COPY(NegativeSortFilterProxyModel)
                                  public:
                                      explicit NegativeSortFilterProxyModel(QObject* parent = Q_NULLPTR) : QSortFilterProxyModel(parent){}
                                  protected:
                                      bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const Q_DECL_OVERRIDE{
                                          return !QSortFilterProxyModel::filterAcceptsRow(source_row,source_parent);
                                      }
                                  };
                                  int main(int argc, char *argv[])
                                  {
                                      QApplication a(argc,argv);
                                      QWidget mainWid;
                                      QComboBox* combo1=new QComboBox(&mainWid);
                                      QComboBox* combo2=new QComboBox(&mainWid);
                                      QHBoxLayout* mainLay = new QHBoxLayout(&mainWid);
                                      mainLay->addWidget(combo1);
                                      mainLay->addWidget(combo2);
                                      QStringListModel* comboModel=new QStringListModel(QStringList() << "Item1" << "Item2" << "Item3",&mainWid);
                                      NegativeSortFilterProxyModel* comboFilter = new NegativeSortFilterProxyModel(&mainWid);
                                      QObject::connect(combo1, QOverload<const QString&>::of(&QComboBox::currentIndexChanged),comboFilter,[comboFilter](const QString &text)->void{comboFilter->setFilterRegExp('^'+QRegExp::escape(text)+'$');});
                                      comboFilter->setSourceModel(comboModel);
                                      combo1->setModel(comboModel);
                                      combo2->setModel(comboFilter);
                                      mainWid.show();
                                      return a.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
                                  2

                                  • Login

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