Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to use findData() from QComboBox to find one element from QList<QVariant> ?



  • Hello,

    typedef struct
    {
        wchar_t a[256];
        wchar_t b[256];
        wchar_t c[256];
    } ABC;
    
    box = new QComboBox(this);
    for(int i=0; i<5; i++)
        {
            ABC p;
            QString x=QString::number(3*i);
            memcpy(p.a,x.toStdWString().c_str(),100);
            QString x2=QString::number(3*i+1);
            memcpy(p.b,x2.toStdWString().c_str(),100);
            QString x3=QString::number(3*i+2);
            memcpy(p.c,x3.toStdWString().c_str(),100);
            box->addItem(QString::fromWCharArray(p.a),QList<QVariant>()<<QString::fromWCharArray(p.a)<<QString::fromWCharArray(p.b)<<QString::fromWCharArray(p.c));
        }
    
        qInfo()<<box->findData();    /////// here
    

    I would like to find data "7" to find the index of item. The problem is that - I don't have simple

    addItem(QString::fromWCharArray(p.a), p.b);
    

    but QList<QVariant>().

    How can I find index of item by p.b?

    Here the answer should be 2. When I try:

    qInfo()<<box->findData("7");  
    

    I get -1.



  • @TomNow99

    box->findText("7",Qt::MatchContains);
    

    EDIT: this isn't solution.



  • @TomNow99
    Since it's not clear how findData() would help you do this, in the time taken to ask the question I would just search the items explicitly instead of bothering with findData(), which is only a convenience function?



  • @JonB I don't understand you. Really. I find example:

    QComboBox* combo = new QComboBox; 
    combo->addItem("100",100.0); // 2nd parameter can be any Qt type 
    combo->addItem ..... 
    
    float value=100.0; 
    int index = combo->findData(value); 
    if (index != -1) { // -1 for not found 
        combo->setCurrentIndex(index); 
    }
    

    So I see that I can use findData to find something what I give as the second parameter to addItem().

    I don't have that simple situation as in this example which I give.

    I have QList<QVariant> and I ask about any snippet which give me something like:

     qInfo()<<box->findData(QList<QVariant>()[1]=="7");
    

    Yes, I know. This example above not make sense. But I show you that maybe there is a tricky way to do what I think about.



  • @TomNow99
    I don't understand you either :) Really.

    Since as you correctly say QComboBox::findData() does not seem to be set up to allow for finding the complicated user data value you pass to addItem() --- plus, I think (but not 100% sure from what you write) you only want to search some of what you put in there, I think the p.b value which is in list element #1 --- I don't understand why you try to use findData() for your situation. It's like trying to fit a square peg into a round hole.

    Yes, findData() works for where the user data is a simple string. But that's not what you have. And as you say, no you can't do something like findData(QList<QVariant>()[1]=="7"). You have some list of somethings, and findData() does not have a Qt::MatchFlags flags which offers to search in a list.

    So you need to do that test in your own code, on visiting each element. All you need to do it yourself is something like:

    for (int index = 0; index < combo->count(); index++)
    {
        QVariant v = combo->itemData(index, Qt::UserRole);
        QList<QVariant> list = qobject_cast< QList<QVariant> >(v);
        if (list[1] == "7")
            return index;
    }
    return -1;
    

    I admit you'll have to get the bit casting/getting the QList out of the value right, but that's the approach.

    But I show you that maybe there is a tricky way to do what I think about.

    It's only that tricky if you make it that way by trying to do it via findData() :)

    BTW, before you/anyone else suggests this. You could "simplify" by not actually storing that list of values in the user data role. If, say, you stored the list as a string with |s at the beginning, end, and between each element, so it looked like |a|b|c|, then you could indeed use

    find("|b|", Qt::MatchContains)
    

    Provided you were happy | could not occur in the strings, and b can only occur in p.b. But that's not what you asked, you stated you want to store the list in the user value. Only you know what you need to store there.



  • @JonB Perfect :) Thank you


  • Qt Champions 2019

    @TomNow99 Then please mark this topic as solved, thx.




Log in to reply