QAbstractItemModel::match bug?



  • 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


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Did you check the content of myValue ?



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

    Any idea?



  • 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?????????



  • @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."



  • 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);
    }
    }
    


  • @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.



  • @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


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.