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. GUI Freeze in loop
QtWS25 Last Chance

GUI Freeze in loop

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 5 Posters 5.1k 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
    jemazter
    wrote on last edited by
    #1

    Hello.

    I have a loop in my code for reading a .txt file. When reading that file the GUI freezes, i tried

    QCoreApplication::processEvents();
    

    But it still freezes. Can someone give me a tip on how to run this on a separate thread or something like this?

    if (!file.open(QIODevice::ReadOnly))
        {
           qDebug() << file.errorString();
           ui->textBrowser->append(file.errorString());
        }    
        while (!file.atEnd())
        {
           QByteArray line = file.readLine();
           wordList.append(line.split(',').first());
          //  QCoreApplication::processEvents();
        }
    

    Thanks.

    A D 2 Replies Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi
      Im a bit surprised it still lagged with processEvents()

      Anyway, you can use a worker object and run that in a thread.
      It can then emit signal to tell main its finished.

      http://wiki.qt.io/QThreads_general_usage

      1 Reply Last reply
      5
      • J jemazter

        Hello.

        I have a loop in my code for reading a .txt file. When reading that file the GUI freezes, i tried

        QCoreApplication::processEvents();
        

        But it still freezes. Can someone give me a tip on how to run this on a separate thread or something like this?

        if (!file.open(QIODevice::ReadOnly))
            {
               qDebug() << file.errorString();
               ui->textBrowser->append(file.errorString());
            }    
            while (!file.atEnd())
            {
               QByteArray line = file.readLine();
               wordList.append(line.split(',').first());
              //  QCoreApplication::processEvents();
            }
        

        Thanks.

        A Offline
        A Offline
        ambershark
        wrote on last edited by
        #3

        @jemazter Yea you definitely want your heavy non GUI operations in their own threads. This will keep your GUI responsive even under load.

        Qt makes this quite easy (well as easy as threading ever can be) and mrjj sent ya a link to that.

        If you need help with the threading or don't understand the docs, let me know and I can show you an example.

        My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

        J 1 Reply Last reply
        4
        • J jemazter

          Hello.

          I have a loop in my code for reading a .txt file. When reading that file the GUI freezes, i tried

          QCoreApplication::processEvents();
          

          But it still freezes. Can someone give me a tip on how to run this on a separate thread or something like this?

          if (!file.open(QIODevice::ReadOnly))
              {
                 qDebug() << file.errorString();
                 ui->textBrowser->append(file.errorString());
              }    
              while (!file.atEnd())
              {
                 QByteArray line = file.readLine();
                 wordList.append(line.split(',').first());
                //  QCoreApplication::processEvents();
              }
          

          Thanks.

          D Offline
          D Offline
          Defohin
          wrote on last edited by
          #4

          @jemazter You can also check the QtConcurrent Word Count Example.

          1 Reply Last reply
          1
          • A ambershark

            @jemazter Yea you definitely want your heavy non GUI operations in their own threads. This will keep your GUI responsive even under load.

            Qt makes this quite easy (well as easy as threading ever can be) and mrjj sent ya a link to that.

            If you need help with the threading or don't understand the docs, let me know and I can show you an example.

            J Offline
            J Offline
            jemazter
            wrote on last edited by jemazter
            #5

            @ambershark

            Hi. If you can show some examples i would appreciate it, i read the documentation but still didn't understand it quite well.

            A 2 Replies Last reply
            0
            • J jemazter

              @ambershark

              Hi. If you can show some examples i would appreciate it, i read the documentation but still didn't understand it quite well.

              A Offline
              A Offline
              ambershark
              wrote on last edited by
              #6

              @jemazter Yea threading is complicated. Even when Qt makes it easy, it is still tricky.

              I'll write up a quick little program to show you how to do it.

              My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

              1 Reply Last reply
              0
              • J jemazter

                @ambershark

                Hi. If you can show some examples i would appreciate it, i read the documentation but still didn't understand it quite well.

                A Offline
                A Offline
                ambershark
                wrote on last edited by
                #7

                @jemazter Ok here is a fully working example... Please note that the thread will create a 1GB file in order to cause enough delay so you can see the GUI is still responsive. It is called deleteme.txt. Make sure to clean it up. :)

                tmp.pro:

                TEMPLATE = app
                TARGET = tmp
                INCLUDEPATH += .
                QT += gui widgets
                
                # Input
                HEADERS += window.h worker.h
                SOURCES += main.cpp window.cpp worker.cpp
                

                main.cpp:

                #include <QApplication>
                #include "window.h"
                
                int main(int ac, char **av)
                {
                        QApplication app(ac, av);
                        Window w;
                        w.show();
                        return app.exec();
                }
                

                window.h:

                #ifndef window_h
                #define window_h
                
                #include <QWidget>
                
                class QProgressBar;
                class QPushButton;
                
                class Window : public QWidget
                {
                        Q_OBJECT
                
                public:
                        Window(QWidget *parent=0);
                        virtual ~Window();
                
                private:
                        void startProgress();
                        QProgressBar *pb_;
                        QPushButton *button_;
                
                private slots:
                        void threadDone(bool success);
                };
                
                #endif
                

                window.cpp:

                #include "window.h"
                #include <QPushButton>
                #include <QTextEdit>
                #include <QVBoxLayout>
                #include <QThread>
                #include <QProgressBar>
                #include <QMessageBox>
                #include "worker.h"
                
                Window::Window(QWidget *parent)
                        : QWidget(parent)
                {
                        // set up our gui
                        auto layout = new QVBoxLayout();
                        button_ = new QPushButton("Start Thread");
                        auto textEdit = new QTextEdit(); // this is here to type in while the thread run
                s to test responsiveness
                        pb_ = new QProgressBar();
                        layout->addWidget(textEdit);
                        layout->addWidget(pb_);
                        layout->addWidget(button_);
                        setLayout(layout);
                
                        // set up the thread for our worker and move it to the thread
                        auto worker = new Worker();
                        auto thread = new QThread();
                        worker->moveToThread(thread);
                
                        // starts writing a file when start thread is clicked
                        connect(button_, &QPushButton::clicked, worker, &Worker::doSomething);
                
                        // starts a progress bar and disables start thread button
                        connect(button_, &QPushButton::clicked, this, &Window::startProgress);
                
                        // tells our window here that our thread is done
                        connect(worker, &Worker::finished, this, &Window::threadDone);
                
                        // cleans up memory
                        connect(worker, &Worker::finished, thread, &QThread::quit);
                        connect(worker, &Worker::finished, worker, &Worker::deleteLater);
                        connect(worker, &Worker::finished, thread, &QThread::deleteLater);
                
                        thread->start();
                }
                
                Window::~Window()
                {
                }
                
                void Window::threadDone(bool success)
                {
                        // stop progress bar
                        pb_->setMaximum(100);
                        pb_->setValue(100);
                
                        if (success)
                                QMessageBox::information(this, "Result", "Success!");
                        else
                                QMessageBox::information(this, "Result", "Failure!");
                }
                
                void Window::startProgress()
                {
                        // disable our start button
                        button_->setEnabled(false);
                
                        // set our progress bar to "busy" mode
                        pb_->setMinimum(0);
                        pb_->setMaximum(0);
                }
                

                worker.h:

                #ifndef worker_h
                #define worker_h
                
                #include <QObject>
                
                class Worker : public QObject
                {
                        Q_OBJECT
                
                public:
                        Worker();
                
                public slots:
                        void doSomething();
                
                signals:
                        void finished(bool success);
                };
                
                #endif
                

                worker.cpp:

                #include "worker.h"
                #include <QFile>
                
                Worker::Worker()
                {
                }
                
                void Worker::doSomething()
                {
                        // write a 1000MB file byte by byte
                        // that should take long enough to test this
                
                        QFile f("deleteme.txt");
                        if (!f.open(QIODevice::Text | QIODevice::WriteOnly))
                        {
                                // we failed..
                                emit finished(false);
                        }
                
                        auto size = 1024*1000000;
                        for (auto i=0;i<size;++i)
                        {
                                f.write("1");
                        }
                
                        f.close();
                        emit finished(true);
                }
                

                Hope that helps, let me know if you need any part explained. :)

                My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

                M 1 Reply Last reply
                4
                • A ambershark

                  @jemazter Ok here is a fully working example... Please note that the thread will create a 1GB file in order to cause enough delay so you can see the GUI is still responsive. It is called deleteme.txt. Make sure to clean it up. :)

                  tmp.pro:

                  TEMPLATE = app
                  TARGET = tmp
                  INCLUDEPATH += .
                  QT += gui widgets
                  
                  # Input
                  HEADERS += window.h worker.h
                  SOURCES += main.cpp window.cpp worker.cpp
                  

                  main.cpp:

                  #include <QApplication>
                  #include "window.h"
                  
                  int main(int ac, char **av)
                  {
                          QApplication app(ac, av);
                          Window w;
                          w.show();
                          return app.exec();
                  }
                  

                  window.h:

                  #ifndef window_h
                  #define window_h
                  
                  #include <QWidget>
                  
                  class QProgressBar;
                  class QPushButton;
                  
                  class Window : public QWidget
                  {
                          Q_OBJECT
                  
                  public:
                          Window(QWidget *parent=0);
                          virtual ~Window();
                  
                  private:
                          void startProgress();
                          QProgressBar *pb_;
                          QPushButton *button_;
                  
                  private slots:
                          void threadDone(bool success);
                  };
                  
                  #endif
                  

                  window.cpp:

                  #include "window.h"
                  #include <QPushButton>
                  #include <QTextEdit>
                  #include <QVBoxLayout>
                  #include <QThread>
                  #include <QProgressBar>
                  #include <QMessageBox>
                  #include "worker.h"
                  
                  Window::Window(QWidget *parent)
                          : QWidget(parent)
                  {
                          // set up our gui
                          auto layout = new QVBoxLayout();
                          button_ = new QPushButton("Start Thread");
                          auto textEdit = new QTextEdit(); // this is here to type in while the thread run
                  s to test responsiveness
                          pb_ = new QProgressBar();
                          layout->addWidget(textEdit);
                          layout->addWidget(pb_);
                          layout->addWidget(button_);
                          setLayout(layout);
                  
                          // set up the thread for our worker and move it to the thread
                          auto worker = new Worker();
                          auto thread = new QThread();
                          worker->moveToThread(thread);
                  
                          // starts writing a file when start thread is clicked
                          connect(button_, &QPushButton::clicked, worker, &Worker::doSomething);
                  
                          // starts a progress bar and disables start thread button
                          connect(button_, &QPushButton::clicked, this, &Window::startProgress);
                  
                          // tells our window here that our thread is done
                          connect(worker, &Worker::finished, this, &Window::threadDone);
                  
                          // cleans up memory
                          connect(worker, &Worker::finished, thread, &QThread::quit);
                          connect(worker, &Worker::finished, worker, &Worker::deleteLater);
                          connect(worker, &Worker::finished, thread, &QThread::deleteLater);
                  
                          thread->start();
                  }
                  
                  Window::~Window()
                  {
                  }
                  
                  void Window::threadDone(bool success)
                  {
                          // stop progress bar
                          pb_->setMaximum(100);
                          pb_->setValue(100);
                  
                          if (success)
                                  QMessageBox::information(this, "Result", "Success!");
                          else
                                  QMessageBox::information(this, "Result", "Failure!");
                  }
                  
                  void Window::startProgress()
                  {
                          // disable our start button
                          button_->setEnabled(false);
                  
                          // set our progress bar to "busy" mode
                          pb_->setMinimum(0);
                          pb_->setMaximum(0);
                  }
                  

                  worker.h:

                  #ifndef worker_h
                  #define worker_h
                  
                  #include <QObject>
                  
                  class Worker : public QObject
                  {
                          Q_OBJECT
                  
                  public:
                          Worker();
                  
                  public slots:
                          void doSomething();
                  
                  signals:
                          void finished(bool success);
                  };
                  
                  #endif
                  

                  worker.cpp:

                  #include "worker.h"
                  #include <QFile>
                  
                  Worker::Worker()
                  {
                  }
                  
                  void Worker::doSomething()
                  {
                          // write a 1000MB file byte by byte
                          // that should take long enough to test this
                  
                          QFile f("deleteme.txt");
                          if (!f.open(QIODevice::Text | QIODevice::WriteOnly))
                          {
                                  // we failed..
                                  emit finished(false);
                          }
                  
                          auto size = 1024*1000000;
                          for (auto i=0;i<size;++i)
                          {
                                  f.write("1");
                          }
                  
                          f.close();
                          emit finished(true);
                  }
                  

                  Hope that helps, let me know if you need any part explained. :)

                  M Offline
                  M Offline
                  meganathan
                  wrote on last edited by
                  #8

                  @ambershark said in GUI Freeze in loop:

                  Hi, i am facing same problem..i tried ur example but startProgress() is not getting emitted on clicked() ? any suggestion

                  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