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 codevoid 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 -
Hi and welcome to devnet,
Did you check the content of
myValue
? -
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 fineQVariant 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: falsevar2
value:0
type: QVariant(int)
isnull: truebut var1==var2 return TRUE !!!!!!!!!
how can a null variant be equal to anything?????????
-
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 fineQVariant 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: falsevar2
value:0
type: QVariant(int)
isnull: truebut 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); } }
-
@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."
@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 aboutbool 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. -
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); } }
@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