QTreeWidget icons issue



  • Hi! I want to display users avatars to treewidget items as icons. I get avatars path and other users info from the database and store it in QVector with the structure.

    MyDB *employeesAccountsDB = new MyDB();
    connect(employeesAccountsDB, &MyDB::accountInfo, [this](QVector<AccountData> dataVector) {
          for (int i = 0; i < dataVector.size(); i++) {
               QTreeWidgetItem *item = new QTreeWidgetItem(treeWidget);
               item->setSizeHint(0, QSize(40, 40));
               item->setText(0, dataVector[i].avatarPath);
               item->setText(1, dataVector[i].username);
               item->setText(2, dataVector[i].email);
               item->setText(3, dataVector[i].group);
               emit avatarPath(dataVector[i].avatarPath);
          }
    
          dataVector.clear();
     });
    

    Info is a GUI class.

    NetManager *avatarNetManager = new NetManager();
    connect(this, &Info::avatarPath, avatarNetManager, &NetManager::getAvatar);
     connect(avatarNetManager, &NetManager::image, [this](QPixmap avatar, int index) {
            QIcon avatarIcon;
    
            if (!avatar.isNull()) {
                avatarIcon = avatar.scaled(80, 80);
            } else {
                avatarIcon = QPixmap(":/Icon/default_avatar.png").scaled(80, 80);
            }
    
            qDebug() << index;
            treeWidget->topLevelItem(index)->setIcon(0, avatarIcon);
      });
    
    int index = 0; // initialized as global variable in the `NetManager` constructor
    void NetManager::getAvatar(QString path)
    {
        networkManager = new QNetworkAccessManager(this);
        networkManager->get(QNetworkRequest(QUrl(path)));
    
        connect(networkManager, &QNetworkAccessManager::finished, [this](QNetworkReply *avatarNetReply) {
            QPixmap avatarPixmap;
            avatarPixmap.loadFromData(avatarNetReply->readAll());
            emit image(avatarPixmap, index);
            index++;
            avatarNetReply->close();
            avatarNetReply->deleteLater();
            networkManager->deleteLater();
            emit finished();
        });
    }
    

    All works well but the avatars don't relate to the users. Any ideas how to collect and retrieve them to the appropriate user? Thanks.

    Updated:
    For example, first icon is Ok, third icon should be on the second item and second icon should be on third item.

    0_1521551133400_2018-03-20_150423.png

    I need something to maintain the order of the icons.

    The problems are with the images indexes.

    "images/avatar/27890.jpg" 0
    "images/avatar/4_SummerSlam_2016.jpg" 1
    "images/avatar/17_maxresdefault.jpg" 2
    FINISHED
    QPixmap(QSize(277, 400),depth=32,devicePixelRatio=1,cacheKey=0xed00000190) 1
    FINISHED
    QPixmap(QSize(380, 400),depth=32,devicePixelRatio=1,cacheKey=0xef00000190) 0
    FINISHED
    QPixmap(QSize(1280, 720),depth=32,devicePixelRatio=1,cacheKey=0xf2000002d0) 2
    


  • I will not discuss the design choices otherwise I'd spend my whole week typing, I'll just debug your code.
    The problem is that you are passing index in the lambda by reference (through this) but you use it as it was by value.
    change

    connect(networkManager, &QNetworkAccessManager::finished, [this](QNetworkReply *avatarNetReply) {
            QPixmap avatarPixmap;
            avatarPixmap.loadFromData(avatarNetReply->readAll());
            emit image(avatarPixmap, index);
            index++;
            avatarNetReply->close();
            avatarNetReply->deleteLater();
            networkManager->deleteLater();
            emit finished();
        });
    

    to (make sure you have #include <functional>

    const auto replyLambda = [this](QNetworkReply *avatarNetReply, int idx) {
            QPixmap avatarPixmap;
            avatarPixmap.loadFromData(avatarNetReply->readAll());
            emit image(avatarPixmap, idx);
            avatarNetReply->close();
            avatarNetReply->deleteLater();
            networkManager->deleteLater();
            emit finished();
        };
    connect(networkManager, &QNetworkAccessManager::finished,this,std::bind(replyLambda,std::placeholders::_1, index++));
    


  • @VRonin

    Thanks for the code, but the output is the same:

    0_1521568367370_2018-03-20_195226.png

    The issue is still present.



  • I have fixed it by QString variable to hold the avatar path and QStringList to hold other user info and when image is retrieved from the path I do the following:

    MyDB *employeesAccountsDB = new MyDB();
    connect(employeesAccountsDB, &MyDB::accountInfo, [this](QPixmap avatar, QStringList accountInfo) {
           QIcon avatarIcon;
    
            if (!avatar.isNull()) {
                avatarIcon = avatar.scaled(80, 80);
            } else {
                avatarIcon = QPixmap(":/Icon/default_avatar.png").scaled(80, 80);
            }
    
            QTreeWidgetItem *item = new QTreeWidgetItem(treewidget);
            item->setIcon(0, avatarIcon);
            item->setSizeHint(0, QSize(40, 40));
    
            for (int i = 0; i < accountInfo.size(); i++) {
                 item->setText(i, accountInfo.at(i));
            }
     });
    

    0_1521578165291_2018-03-20_223557.png

    All works well.


Log in to reply
 

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