Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

    Unsolved GUI Freeze in loop

    General and Desktop
    5
    8
    4226
    Loading More Posts
    • 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
      jemazter last edited by

      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 Reply Quote 0
      • mrjj
        mrjj Lifetime Qt Champion last edited by

        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 Reply Quote 5
        • A
          ambershark @jemazter last edited by

          @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 Reply Quote 4
          • D
            Defohin @jemazter last edited by

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

            1 Reply Last reply Reply Quote 1
            • J
              jemazter @ambershark last edited by 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 2 Replies Last reply Reply Quote 0
              • A
                ambershark @jemazter last edited by

                @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 Reply Quote 0
                • A
                  ambershark @jemazter last edited by

                  @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 Reply Quote 4
                  • M
                    meganathan @ambershark last edited by

                    @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 Reply Quote 0
                    • First post
                      Last post