removing item in qlistwidget through string



  • is there a function in QListWidget class like QListWidget::remove("item");

    or should i make a loop and find the item every index?



  • This something like :

    QListWidget::removeItemWidget(QListWidgetItem * item)



  • in http://www.qtcentre.org/threads/9343-remove-item-from-QListWidget
    it says QListWidget::removeItemWidget(QListWidgetItem * item) doesnt delete the item.

    so i did this :
    for ( int a = 0; a < ui->clientList->count()+1; a++ )
    {
    if ( ui->clientList->item(a)->text() == QString::fromStdString(name) )
    {
    delete ui->clientList->takeItem(a);
    }
    }

    any better solution?


  • Moderators

    remove +1 in

    for ( int a = 0; a < ui->clientList->count()+1; a++ )
    

    If you want to remove everything you can just call

    ui->clientList->clear();
    

  • Moderators

    @Pogi
    takeItem changes the count and the item at current index so your loop skips an item every time you take something from it. It's generally bug-prone to modify any container you're looping through.
    Also constructing the same string in every loop pass is not a good idea.

    What you can do instead is this:

    qDeleteAll(ui->clientList->findItems(QString::fromStdString(name), Qt::MatchFixedString));


  • @Chris-Kawa
    takeItem changes the count and the item at current index
    im aware of that thanks, i dont have any problem here since i only need to delete one item. also i forgot to put break inside the if statement so you thought i will delete multiple items in one set of loop

    Also constructing the same string in every loop pass is not a good idea.
    what do you mean?

    and ive noticed that this code:

            for ( int a = 0; a < ui->clientList->count(); a-- )
            {
                if ( ui->clientList->item(a)->text() == QString::fromStdString(name) )
                {
                    delete ui->clientList->takeItem(a);
                    break;
                }
            }
    

    can only delete the first item, i mean let say i have 3 items in my QListWidget object.
    if the if statement is true and a is 0, it deletes the item at row 0 successfully
    but if the if statement is true and a is 1 or 2, it doesnt delete the item, it only highlights the item as if you mouseclick on it.


  • Moderators

    what do you mean?

    I mean this: QString::fromStdString(name). It creates new instance of QString, allocates storage and makes a copy of the std::string data. And you're doing it in every loop pass while you could be doing it once in advance.

    for ( int a = 0; a < ui->clientList->count(); a-- )

    You're starting at 0 and then you a-- into oblivion ;)

    You could of course start at the end and iterate backwards, but isn't a straight one-liner better than an 8 line loop with conditional expression? It's easier to read and very hard to get wrong (no loops, ifs, counters and breaks...).



  • @Chris-Kawa
    It creates new instance of QString, allocates storage and makes a copy of the std::string data
    i dont know that, i thought its just like a static casting or stream

    You're starting at 0 and then you a-- into oblivion
    that was just a typo, it is actually a++ in my code

    this one does nothing:
    qDeleteAll(ui->clientList->findItems(QString::fromStdString(name), Qt::MatchFixedString));
    can you link me the documentation for qDeleteAll?

    EDIT: nevermind the documentation i found it



  • qDeleteAll(ui->clientList->findItems(QString::fromStdString(name), Qt::MatchFixedString));

    this does the same as my for loop, it highlights the item as if you mouseclicked on it
    is it a bug?


  • Moderators

    dont know that, i thought its just like a static casting or stream

    It's not. It's a copy and conversion to UTF.

    this one does nothing

    It does what you wanted - removes and deletes all QListWidgetItems with given text. If it doesn't then there must be something else wrong in your code. Can you make a minimal example that shows the problem?



  • @Chris-Kawa

    Can you make a minimal example that shows the problem?
    it can only delete the first item in the QListWidget object.

    im making a chat app. when a user disconnects, he will be disconnected and his/her name will be removed in the QListWidget.

    im using SFML network

    so this my destructor for client, it runs when that client disconnects.
    ClientManager::~ClientManager()
    {
    sf::Packet name;
    name << Login::getName().toStdString();
    if ( client.send(name) == 0 )
    {
    //successfully sends the name of the client the disconnects
    // the server will receive its name and send the info to all clients
    }
    }

    void ClientManager::receiveMessage()
    {
    if ( client.receive(packet) == 0 )
    {
    emit displayMessage();
    }
    }

    slot:
    void MainWindow::displayMessage()
    {
    qDebug() << QString::fromStdString(name) << " has been disconnected";
    qDeleteAll(ui->clientList->findItems(QString::fromStdString(name), Qt::MatchFixedString));

    }

    minimal example for server side:
    void ServerManager::ReceivePacketAndSendToAllClientExceptTheSender()
    {

    }

    as you can see in the displayMessage() slot function, the:
    qDebug() << QString::fromStdString(name) << " has been disconnected";
    prints correctly, so the name received from the server is correct, so i think the only wrong is qDeleteAll(); im lost now :(



  • @Chris-Kawa I have fixed it, you're right. it is something else in my code.
    i just found and realized it when another part of my program is showing the problem, this time the problem is showing more detailed so i managed to find out.


Log in to reply
 

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