Qt Forum

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

    Update: Forum Guidelines & Code of Conduct


    Qt World Summit: Early-Bird Tickets

    Solved QAbstractItemModel::match bug?

    General and Desktop
    4
    8
    1594
    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.
    • K
      Koyi last edited by

      I have a QCombobox wich model is a QSqlTableModel populated with a DataBase table:
      Integer | String
      =-=-=-=-=-=-=-=
              |
      =-=-=-=-=-=-=-=
          0 | Normal
      =-=-=-=-=-=-=-=
          1 | Leve
      =-=-=-=-=-=-=-=
          2 | Moderado
      =-=-=-=-=-=-=-=
          3 | Severo
      =-=-=-=-=-=-=-=
         
      the combobox works fine
      but when I try to set the value in combo acording with the database table, I use this code

      void MyComboBox::setValor(QVariant myValue)
      {
      QModelIndexList myFinded=this->model()->match(this->model()->index(0,0),Qt::DisplayRole,myValue,5,Qt::MatchFlags(Qt::MatchExactly || Qt::MatchWrap));
      
      this->setCurrentIndex(myFinded[0].row());
      }
      

      When myValue is 1, myFinded has 1 Index (corresponding to row 2)
      When myValue is 2, myFinded has 1 Index (corresponding to row 3)
      and so on
      but when myValue is 0, myFinded has 2 Index (corresponding to row 0 and 1)
      I don't understand why. Is this a bug? Or am I doing something wrong

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

        Hi and welcome to devnet,

        Did you check the content of myValue ?

        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 0
        • K
          Koyi last edited by

          Hi
          thanks for a quick answer.
          yes, of course I checked the value of myValue and de value of MyFinded (debug mode).

          Any idea?

          1 Reply Last reply Reply Quote 0
          • K
            Koyi last edited by

            I found the problem (not the solution):(

            QAbstractItemModel::match compares each value from the model with the searched value and return the indexes that match.
            it uses the operator== method of QVariant, but it doesn't work fine

            QVariant var1=QVariant(0); // variant containing the integer 0
            
            QSqlQueryModel *miConsulta=new QSqlQueryModel;
            
            miConsulta->setQuery("Select Valor, Descripcion From myTable");
            QVariant var2=miConsulta->record(0).value(0);
            
            

            I get
            var1
            value: 0
            type: QVariant(int)
            isnull: false

            var2
            value:0
            type: QVariant(int)
            isnull: true

            but var1==var2 return TRUE !!!!!!!!!

            how can a null variant be equal to anything?????????

            jeremy_k 1 Reply Last reply Reply Quote 0
            • jeremy_k
              jeremy_k @Koyi last edited by

              @Koyi The documentation mentions this:

              "A variant is considered null if it contains a default constructed value or a built-in type instance that has an isNull method, in which case the result would be the same as calling isNull on the wrapped object.

              Warning: The result of the function doesn't affect == operator, which means that two values can be equal even if one of them is null and another is not."

              Asking a question about code? http://eel.is/iso-c++/testcase/

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

                can you consider manual matching?

                
                void MyComboBox::setValor(const QVariant& myValue, int column = 0, int role = Qt::DisplayRole, const QModelIndex& parent=QModelIndex())
                {
                if(myValue.isNull()) return;
                const int rowCount= model()->rowCount(parent);
                for(int i=0;i<rowCount;++i){
                const QVariant currVal = model()->index(i,column,parent ).data(role );
                if(currVal.isNull()) continue;
                if(currVal == myValue)
                return setCurrentIndex(i);
                }
                }
                

                "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 Reply Quote 2
                • K
                  Koyi @jeremy_k last edited by

                  @jeremy_k said in QAbstractItemModel::match bug?:

                  @Koyi The documentation mentions this:

                  "A variant is considered null if it contains a default constructed value or a built-in type instance that has an isNull method, in which case the result would be the same as calling isNull on the wrapped object.

                  Warning: The result of the function doesn't affect == operator, which means that two values can be equal even if one of them is null and another is not."

                  You are right.
                  I expected that operator== were about

                  bool operator==(const QVariant &v1, const QVariant &v2)
                  {
                    if (isnull(v1) || isnull(v2))
                    return false;
                  .......
                  }
                  

                  because I think a null value cannot be compared with anything.
                  Obviously I was wrong.

                  1 Reply Last reply Reply Quote 0
                  • K
                    Koyi @VRonin last edited by

                    @VRonin said in QAbstractItemModel::match bug?:

                    can you consider manual matching?

                    
                    void MyComboBox::setValor(const QVariant& myValue, int column = 0, int role = Qt::DisplayRole, const QModelIndex& parent=QModelIndex())
                    {
                    if(myValue.isNull()) return;
                    const int rowCount= model()->rowCount(parent);
                    for(int i=0;i<rowCount;++i){
                    const QVariant currVal = model()->index(i,column,parent ).data(role );
                    if(currVal.isNull()) continue;
                    if(currVal == myValue)
                    return setCurrentIndex(i);
                    }
                    }
                    

                    yes, it seems to be the approach.
                    thanks

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