Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [Solve]Strange behavior program with this code
Forum Updated to NodeBB v4.3 + New Features

[Solve]Strange behavior program with this code

Scheduled Pinned Locked Moved General and Desktop
6 Posts 4 Posters 2.3k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    Ruzik
    wrote on last edited by
    #1

    Hello!
    I have one classes which is the successor of QThread, i use it for geting icon.
    But when i try to use it my program compyle without any mistakes, but it is not visible and does not work.
    This is my class(sory for big code, RDownloader is auxiliary class) :
    @#ifndef RICONMANAGER_H
    #define RICONMANAGER_H

    #include <QThread>
    #include <QIcon>
    #include <QCoreApplication>
    #include <QFile>
    #include <QFileInfo>
    #include <QList>
    #include <QNetworkAccessManager>
    #include <QNetworkRequest>
    #include <QNetworkReply>
    #include <QSslError>
    #include <QStringList>
    #include <QTimer>
    #include <QUrl>
    #include <QSettings>
    #include <QFileIconProvider>
    #include <QDir>
    #include <QVariant>

    #include <Classes/RDataItemModel/RDataItemModel.h>
    #include <Classes/RDataItemModel/RDataItem/RDataItem.h>

    //---------Downloader
    class RDownloader: public QObject
    {
    Q_OBJECT
    public:
    explicit RDownloader(RDataItem *);
    private:
    QNetworkAccessManager manager;
    RDataItem *item;

     QString clearWebAdress(QString str);
    

    public slots:
    void downloadFinished(QNetworkReply *reply);
    };
    //---------RIconManager
    class RIconManager : public QThread
    {
    Q_OBJECT
    public:
    explicit RIconManager(RDataItem *parent);
    private:
    void chooseIconWithData(const QString &data);
    void chooseIconWithType(const RDataItemModel::itemType &type);

    RDataItem *item;
    

    protected:
    void run();
    };

    #endif // RICONMANAGER_H@
    @#include "RIconManager.h"

    //------Downloader
    RDownloader::RDownloader(RDataItem it)
    {
    item = it;
    QNetworkRequest request(QUrl(clearWebAdress(it->text())));
    manager.get(request);
    connect(&manager, SIGNAL(finished(QNetworkReply
    )),
    SLOT(downloadFinished(QNetworkReply*)));
    }

    QString RDownloader::clearWebAdress(QString str)
    {
    return str;
    }

    void RDownloader::downloadFinished(QNetworkReply *reply)
    {
    if (!reply->error())
    if (QVariant(reply->readAll()).convert(QVariant::Icon))
    {
    QIcon icon = qvariant_cast<QIcon>(QVariant(reply->readAll()));
    item->setIcon(icon);
    }

     reply->deleteLater();
     deleteLater();
    

    }

    //-------RIconManager
    RIconManager::RIconManager(RDataItem *parent)
    {
    item = parent;
    run();
    }

    void RIconManager::run()
    {
    QSettings settings(QDir::currentPath() + "/settings.ini", QSettings::IniFormat);
    QIcon icon;

    if (settings.value("design/iconMode", "simple").toString() == "advanced")
        chooseIconWithData(item->text());
    if (settings.value("design/iconMode", "simple").toString() == "simple")
        chooseIconWithType(RDataItemModel::chooseTypeOfItem(item->text()));
    
    exec&#40;&#41;;
    

    }

    void RIconManager::chooseIconWithData(const QString &data)
    {
    RDataItemModel::itemType type = RDataItemModel::chooseTypeOfItem(data);
    QIcon icon;
    //Internet site
    if (type == RDataItemModel::WebAddress)
    {
    RDownloader *downloader = new RDownloader(item);
    return;
    }

    }
    void RIconManager::chooseIconWithType(const RDataItemModel::itemType &type)
    {
    //Choose simply icon
    }
    @
    RDataItem is successor of QStandardItem
    RDataItemModel is successor of QStandartItemModel
    I think that problem due to the fact that the RIconManager is QThread
    RIconManager called with this code:
    @new RIconManager(dataItem);@

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mlong
      wrote on last edited by
      #2

      I don't believe you can use QIcon in a thread other than the main thread, as it's a GUI element.

      With that said, What is the reason to make this its own thread? QNetworkAccessManager is inherently asynchronous and should be easy to integrate into the main thread.

      [Edit: On second thought, I might be on the wrong path here... need to read the code a little closer.]

      Software Engineer
      My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

      1 Reply Last reply
      0
      • A Offline
        A Offline
        alexisdm
        wrote on last edited by
        #3

        In downloadFinished, you have 2 calls to reply->readAll() where you should only have one (the first one removes all the available data from the device and returns it, and the second one has nothing left to read).

        And I'm pretty sure you can convert a QByteArray to a QIcon by using QVariant, but you could use the buffer to create a QPixmap and then get a QIcon from it:

        @void RDownloader::downloadFinished(QNetworkReply *reply)
        {
        if (reply->error() == QNetworkReply::NoError)
        QByteArray data = reply->readAll();
        // The slot, or at least the following part has to execute in the main thread,
        // because QPixmap (and QIcon) are GUI elements
        QPixmap pixmap;
        pixmap.loadFromData(data);
        if (pixmap.isValid()) {
        item->setIcon(QIcon(pixmap));
        }
        }
        reply->deleteLater();
        deleteLater();
        }@

        1 Reply Last reply
        0
        • R Offline
          R Offline
          Ruzik
          wrote on last edited by
          #4

          Thank you for you help!

          1 Reply Last reply
          0
          • G Offline
            G Offline
            giesbert
            wrote on last edited by
            #5

            By the way, your code does not start the thread:

            @
            RIconManager::RIconManager(RDataItem *parent)
            {
            item = parent;
            run();
            }
            @

            You call the run method inside the constructor, this is not how threads work.
            A thread is started by calling start();

            Nokia Certified Qt Specialist.
            Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

            1 Reply Last reply
            0
            • R Offline
              R Offline
              Ruzik
              wrote on last edited by
              #6

              [quote author="Gerolf" date="1335440000"]By the way, your code does not start the thread:

              @
              RIconManager::RIconManager(RDataItem *parent)
              {
              item = parent;
              run();
              }
              @

              You call the run method inside the constructor, this is not how threads work.
              A thread is started by calling start();[/quote]
              Thank you for your note!

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved