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. QThread Background?
QtWS25 Last Chance

QThread Background?

Scheduled Pinned Locked Moved General and Desktop
9 Posts 4 Posters 5.4k Views
  • 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.
  • J Offline
    J Offline
    jmper
    wrote on last edited by
    #1

    Hey there all is there a way I can have a QThread run in the background and still allow the users to continue doing whatever they want? Or even have the that thread continue ti run, until it's done while the main application exits? Currently I have my main app taking a picture and then a I have a class that I run as a thread, however the user still can't do anything until the thread I launched finishes.

    Any insight would be helpful.

    1 Reply Last reply
    0
    • D Offline
      D Offline
      deimos
      wrote on last edited by
      #2

      Read "this":http://doc.qt.nokia.com/qq/qq27-responsive-guis.html to keep the GUI responsive.
      The thread you run is a child of the main app thread, so when you close it, also the thread will stop. What I could suggest you is make another application called inside the main app.

      hope this help

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

        Threads can do you all you need. I guess you are using them in the wrong way, but there is no way to be sure without seeing the (relevant) code.

        1 Reply Last reply
        0
        • J Offline
          J Offline
          jmper
          wrote on last edited by
          #4

          [quote author="Andre" date="1321254162"]Threads can do you all you need. I guess you are using them in the wrong way, but there is no way to be sure without seeing the (relevant) code. [/quote]

          Here is what I'm currently doing

          capture class headers
          @
          #ifndef CAPIT_H
          #define CAPIT_H

          #include <QMainWindow>
          #include <Qt>
          #include <QtCore>
          #include <QtGui>
          #include <QtGlobal>

          #include "upload.h"

          namespace Ui {
          class CapIt;
          }

          class CapIt : public QMainWindow
          {
          Q_OBJECT

          public:
          QByteArray m_imagedata;
          QPixmap m_screenshot;
          QPoint origin, dest;

          /**
           * Constructor & Destructor
           */
          explicit CapIt(QWidget *parent = 0);
          ~PixlDrop();
          
          /**
           * Functions
           */
          QPixmap shootScreen();
          void screenshotWriteout();
          
          /**
           * Events
           */
          void mouseReleaseEvent(QMouseEvent *event);
          

          private:
          Ui::CapIt *ui;
          upload *upld;

          };

          #endif
          @

          capture class
          @
          void CapIt::mouseReleaseEvent(QMouseEvent *event)
          {
          if (event->button() == Qt::LeftButton)
          {
          dest = event->pos();
          delete selected;
          m_screenshot = shootScreen();
          screenshotWriteout();

              // here is where I call my upload class that that has the QThread subclass and my own
              // run implementation
              upld->run(m_imagedata);
          }
          
          // at this point I would like this part of the app to close as it no longer needed and
          // just keep the upld thread running until the upload has finished.
          

          }@

          upload h
          @
          #ifndef UPLOAD_H
          #define UPLOAD_H

          #include <QMainWindow>
          #include <Qt>
          #include <QtCore>
          #include <QtGui>
          #include <QtGlobal>
          #include <QThread>
          #include <QNetworkAccessManager>
          #include <QNetworkRequest>
          #include <QNetworkReply>

          class upload : public QThread
          {
          Q_OBJECT
          public:
          QByteArray m_uploaddata;

          explicit upload(QObject *parent = 0);
          bool imageUpload();
          void loadImage(QString reply_data);
          QString randomString(int len);
          
          virtual void run(QByteArray imagedata);
          

          private slots:
          void finished_upload();

          private:
          QNetworkAccessManager *net;
          QNetworkReply *reply;

          protected:

          };

          #endif
          @

          upload class
          @
          void upload::run(QByteArray imagedata)
          {
          m_uploaddata = imagedata;
          imageUpload();
          }

          bool upload::imageUpload()
          {
          net = new QNetworkAccessManager(this);

          // setup random image name;
          QString file = randomString(15) + ".png";
          
          QNetworkRequest httpReq;
          httpReq.setUrl(QUrl("http://url.to/upload/"));
          
          QString bound("---------------------------723690991551375881941828858");
          QByteArray data(QString("--"+bound+"\r\n").toAscii());
          data += "Content-Disposition: form-data; name=\"action\"\r\n\r\n";
          data += "\r\n";
          data += QString("--" + bound + "\r\n").toAscii();
          
          data += "Content-Disposition: form-data; name=\"file\"; filename=\"" + file +"\"\r\n";
          data += "Content-Type: image/png\r\n\r\n";
          data += m_uploaddata;
          
          data += "\r\n";
          data += QString("--" + bound + "\r\n").toAscii();
          
          httpReq.setRawHeader(QString("Accept-Encoding").toAscii(), QString("gzip,deflate").toAscii());
          httpReq.setRawHeader(QString("Content-Type").toAscii(),QString("multipart/form-data; boundary=" + bound).toAscii());
          httpReq.setRawHeader(QString("Content-Length").toAscii(), QString::number(data.length()).toAscii());
          
          this->reply = net->post(httpReq, data);
          connect(this->reply, SIGNAL(finished()), this, SLOT(finished_upload()));
          
          return true;
          

          }

          void upload::finished_upload()
          {
          if (this->reply->error() == QNetworkReply::NoError)
          loadImage(QString(reply->readAll()));
          else
          QMessageBox::warning(0, "Error", "Unable to upload image.");

          }

          void upload::loadImage(QString reply_data)
          {
          QStringList parts = reply_data.split(";", QString::SkipEmptyParts);

          if (QDesktopServices::openUrl( QUrl(parts[1]) ))
              QApplication::quit();
          

          }
          @

          1 Reply Last reply
          0
          • A Offline
            A Offline
            andre
            wrote on last edited by
            #5

            Could you please also add the relevant headers?

            1 Reply Last reply
            0
            • J Offline
              J Offline
              jmper
              wrote on last edited by
              #6

              [quote author="Andre" date="1321303094"]Could you please also add the relevant headers?[/quote]

              Added to post.

              1 Reply Last reply
              0
              • A Offline
                A Offline
                andre
                wrote on last edited by
                #7

                You are calling your reimplemented run method directly. That is not how to use QThread. QThread::run is protected. That means, that it is not meant for outside callers. It is meant to be called by start(), once the new thread has actually started. Remember that QThread only manages a thread, it isn't a thread in itself. What's more, you have created an overloaded version of run, one that takes a QByteArray. That method you just call from your GUI thread, and that causes your run method (and everything else it calls in turn) to also be executed in the GUI thread.

                So, you are not really starting the thread anywhere, and the way you reimplemented the run() method is not going to work.

                1 Reply Last reply
                0
                • J Offline
                  J Offline
                  jmper
                  wrote on last edited by
                  #8

                  [quote author="Andre" date="1321305664"]You are calling your reimplemented run method directly. That is not how to use QThread. QThread::run is protected. That means, that it is not meant for outside callers. It is meant to be called by start(), once the new thread has actually started. Remember that QThread only manages a thread, it isn't a thread in itself. What's more, you have created an overloaded version of run, one that takes a QByteArray. That method you just call from your GUI thread, and that causes your run method (and everything else it calls in turn) to also be executed in the GUI thread.

                  So, you are not really starting the thread anywhere, and the way you reimplemented the run() method is not going to work. [/quote]

                  ok how about this

                  capit .h
                  @
                  #ifndef CAPIT_H
                  #define CAPIT_H

                  #include <QMainWindow>
                  #include <Qt>
                  #include <QtCore>
                  #include <QtGui>
                  #include <QtGlobal>

                  #include "upload.h"

                  namespace Ui {
                  class CapIt;
                  }

                  class CapIt : public QMainWindow
                  {
                  Q_OBJECT

                  public:
                  QByteArray m_imagedata;
                  QPixmap m_screenshot;
                  QPoint origin, dest;

                  /**
                   * Constructor & Destructor
                   */
                  explicit CapIt(QWidget *parent = 0);
                  ~PixlDrop();
                  
                  /**
                   * Functions
                   */
                  QPixmap shootScreen();
                  void screenshotWriteout();
                  
                  /**
                   * Events
                   */
                  void mouseReleaseEvent(QMouseEvent *event);
                  

                  private:
                  Ui::CapIt *ui;
                  upload *upld;

                  };

                  #endif
                  @

                  capit .cpp
                  @
                  void CapIt::mouseReleaseEvent(QMouseEvent *event)
                  {
                  if (event->button() == Qt::LeftButton)
                  {
                  dest = event->pos();
                  delete selected;
                  m_screenshot = shootScreen();
                  screenshotWriteout();

                      // spawn new upload thread
                      upload upld(m_imagedata);
                      upld.start();
                  }
                  

                  @

                  upload .h
                  @
                  #ifndef UPLOAD_H
                  #define UPLOAD_H

                  #include <QMainWindow>
                  #include <Qt>
                  #include <QtCore>
                  #include <QtGui>
                  #include <QtGlobal>
                  #include <QThread>
                  #include <QNetworkAccessManager>
                  #include <QNetworkRequest>
                  #include <QNetworkReply>

                  class upload : public QThread
                  {
                  Q_OBJECT

                  public:
                  QByteArray m_uploaddata;

                  // constructor
                  upload(QByteArray r_imagedata, QObject *parent = 0);
                  
                  bool imageUpload();
                  void loadImage(QString reply_data);
                  QString randomString(int len);
                  

                  private slots:
                  void finished_upload();

                  private:
                  QNetworkAccessManager *net;
                  QNetworkReply *reply;

                  protected:
                  virtual void run();

                  };

                  #endif
                  @

                  upload .cpp
                  @
                  #include "upload.h"

                  upload::upload(QByteArray r_imagedata, QObject *parent) : QThread(parent)
                  {
                  m_uploaddata = r_imagedata;
                  }

                  void upload::run()
                  {
                  imageUpload();
                  exec();
                  }

                  bool upload::imageUpload()
                  {
                  net = new QNetworkAccessManager(this);

                  // setup random image name;
                  QString file = randomString(15) + ".png";
                  
                  QNetworkRequest httpReq;
                  httpReq.setUrl(QUrl("http://path.to/upload/"));
                  
                  QString bound("---------------------------723690991551375881941828858");
                  QByteArray data(QString("--"+bound+"\r\n").toAscii());
                  data += "Content-Disposition: form-data; name=\"action\"\r\n\r\n";
                  data += "\r\n";
                  data += QString("--" + bound + "\r\n").toAscii();
                  
                  data += "Content-Disposition: form-data; name=\"file\"; filename=\"" + file +"\"\r\n";
                  data += "Content-Type: image/png\r\n\r\n";
                  data += m_uploaddata;
                  
                  data += "\r\n";
                  data += QString("--" + bound + "\r\n").toAscii();
                  
                  httpReq.setRawHeader(QString("Accept-Encoding").toAscii(), QString("gzip,deflate").toAscii());
                  httpReq.setRawHeader(QString("Content-Type").toAscii(),QString("multipart/form-data; boundary=" + bound).toAscii());
                  httpReq.setRawHeader(QString("Content-Length").toAscii(), QString::number(data.length()).toAscii());
                  
                  this->reply = net->post(httpReq, data);
                  connect(this->reply, SIGNAL(finished()), this, SLOT(finished_upload()));
                  
                  return true;
                  

                  }

                  void upload::finished_upload()
                  {
                  if (this->reply->error() == QNetworkReply::NoError)
                  loadImage(QString(reply->readAll()));
                  else
                  QMessageBox::warning(0, "Error", "Unable to upload image.");

                  }

                  void upload::loadImage(QString reply_data)
                  {
                  QStringList parts = reply_data.split(";", QString::SkipEmptyParts);

                  if (QDesktopServices::openUrl( QUrl(parts[1]) ))
                      QApplication::quit();
                  

                  }
                  @

                  However this results in: QThread: Destroyed while thread is still running

                  1 Reply Last reply
                  0
                  • S Offline
                    S Offline
                    silver47
                    wrote on last edited by
                    #9

                    bq. @// spawn new upload thread
                    upload upld(m_imagedata);
                    upld.start();@

                    The object - upld will be destroyed while you going out of "if(event->button() == Qt::LeftButton)". You should create upld on the heap, not on the stack:
                    @upload *upld = new upload(m_imagedata);
                    upld->start();@

                    sorry for my english :(

                    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