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. Separate QThread to update QDialog's UI
QtWS25 Last Chance

Separate QThread to update QDialog's UI

Scheduled Pinned Locked Moved Unsolved General and Desktop
qthreadqdialoguser interface
6 Posts 2 Posters 5.3k 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.
  • A Offline
    A Offline
    alogim
    wrote on 2 Nov 2015, 16:44 last edited by
    #1

    So, I was using QCoreApplication::processEvents() to update the UI of a QDialog, and I thought QThreads (even to familiarise with them) would have been better.
    I wrote a simple test, with a MainWindow with a unique QPushButton; pressing it, a QDialog is shown, with a qGraphicsView and two buttons, one to pause, and one to stop.
    If you don't want to read all this one, simply check my code.
    I have a class Algorithm that simulates a heavy task (a while loop, inside of which there are two things, a for loop simply printing two values and a function that randomly generates two values). Those two values are returned via a signal to the dialog, so that I can use them to draw a point on the qGraphicsView. Another signal (finished()) is emitted when the while loop ends (that is, when the conditions i < 10000 or running == true are false). Running is a private member variable of the class Algorithm. It is set to false if a user clicks on pause/stop on the dialog. So I have anothe signal, emitted by Dialog, caught by class Algorithm, that sets running to true or false.

    The problem arises since this last signal (setRunning(bool)) is always caught at the end of the loop, when the computations already are ended.
    So I added Qt::DirectConnection and this now is caught when the button is pressed.
    I wonder if there is a better way to do this.
    Thank you in advance.
    I copy here the code, if you don't want to read all the above :D

    //mainwindow.h
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    namespace Ui {
      class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
      Q_OBJECT
    
      public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
      private slots:
    	void on_pushButton_clicked();
    
      private:
    	Ui::MainWindow *ui;
    };
    #endif // MAINWINDOW_H
    

    MainWindow.cpp

    #include "dialog.h"
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    #include <QThread>
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
      ui->setupUi(this);
    }
    
    MainWindow::~MainWindow()
    {
      delete ui;
    }
    
    void MainWindow::on_pushButton_clicked()
    {
      Dialog *d = new Dialog(this);
      d->setAttribute(Qt::WA_DeleteOnClose, true);
      d->show();
      d->doSomething();
    }
    

    dialog.h

    #ifndef DIALOG_H
    #define DIALOG_H
    
    #include "algorithm.h"
    
    #include <QDialog>
    #include <QGraphicsScene>
    #include <QThread>
    
    namespace Ui {
    	class Dialog;
    }
    
    class Dialog : public QDialog
    {
    		Q_OBJECT
    
    	public:
    		explicit Dialog(QWidget *parent = 0);
    		~Dialog();
    
    	private:
    		Ui::Dialog *ui;
    		QGraphicsScene* scene;
    		bool running;
    		int i, c;
    		Algorithm* a;
    
    	signals:
    		void setStatus(bool);
    
    	private slots:
    		void on_pushButton_clicked();
    		void on_pushButton_2_clicked();
    		void draw_point(int x, int y);
    
    	public slots:
    		void doSomething();
    };
    
    #endif // DIALOG_H
    

    dialog.cpp

    #include "algorithm.h"
    #include "dialog.h"
    #include "ui_dialog.h"
    
    #include <QDebug>
    #include <QThread>
    
    Dialog::Dialog(QWidget *parent) :
    	QDialog(parent),
    	ui(new Ui::Dialog)
    {
    	ui->setupUi(this);
    	scene = new QGraphicsScene(this);
    	scene->setSceneRect(0, 0, 200, 200);
    	ui->graphicsView->setScene(scene);
    	ui->graphicsView->setFixedSize(200, 200);
    
    	i = 0;
    	c = 0;
    
    	running = true;
    }
    
    Dialog::~Dialog()
    {
    	delete scene;
    	delete ui;
    }
    
    void Dialog::doSomething()
    {
    	if (c == 0)
    	{
    		QThread* t = new QThread;
    		a = new Algorithm(i, true);
    		a->moveToThread(t);
    		connect (a, SIGNAL(new_point(int,int)), this, SLOT(draw_point(int,int)));
    		connect (t, SIGNAL(started()), a, SLOT(compute()));
    		connect (this, SIGNAL(setStatus(bool)), a, SLOT(setRunning(bool)), Qt::DirectConnection);
    		connect (a, SIGNAL(finished()), t, SLOT(quit()));
    		connect (a, SIGNAL(finished()), a, SLOT(deleteLater()));
    		connect (t, SIGNAL(finished()), t, SLOT(deleteLater()));
    
    		connect (a, SIGNAL(paused()), t, SLOT(quit()));
    		t->start();
    	}
    	else
    	{
    		QThread* t = new QThread;
    		a->moveToThread(t);
    		connect (a, SIGNAL(new_point(int,int)), this, SLOT(draw_point(int,int)));
    		connect (t, SIGNAL(started()), a, SLOT(compute()));
    		connect (this, SIGNAL(setStatus(bool)), a, SLOT(setRunning(bool)), Qt::DirectConnection);
    		connect (a, SIGNAL(finished()), t, SLOT(quit()));
    		connect (a, SIGNAL(finished()), a, SLOT(deleteLater()));
    		connect (t, SIGNAL(finished()), t, SLOT(deleteLater()));
    
    		connect (a, SIGNAL(paused()), t, SLOT(quit()));
    		t->start();
    	}
    	c++;
    }
    
    void Dialog::on_pushButton_clicked()
    {
    	running = false;
    	ui->pushButton->setEnabled(false);
    	ui->pushButton_2->setEnabled(false);
    	emit setStatus(running);
    }
    
    void Dialog::on_pushButton_2_clicked()
    {
    	if (running)
    	{
    		running = false;
    		ui->pushButton_2->setText("Resume");
    		emit setStatus(running);
    	}
    	else
    	{
    		running = true;
    		ui->pushButton_2->setText("Pause");
    		emit setStatus(running);
    		doSomething();
    	}
    }
    
    void Dialog::draw_point(int x, int y)
    {
    	scene->addEllipse(x, y, 1.0, 1.0);
    }
    

    algorithm.h

    #ifndef ALGORITHM_H
    #define ALGORITHM_H
    
    #include <QObject>
    
    class Algorithm : public QObject
    {
    		Q_OBJECT
    	public:
    		Algorithm(const int &i, const bool& running);
    		~Algorithm();
    
    	private:
    		int i;
    		bool running;
    
    	signals:
    		void new_point(int, int);
    		void finished();
    		void paused();
    
    	public slots:
    		void setRunning(bool value);
    		void compute();
    };
    
    #endif // ALGORITHM_H
    

    algorithm.cpp

    #include "algorithm.h"
    
    #include <QDebug>
    
    Algorithm::Algorithm(const int &i, const bool &running)
    {
    	this->i = i;
    	this->running = running;
    }
    
    Algorithm::~Algorithm()
    {}
    
    void Algorithm::compute()
    {
    	while ((i < 10000) && running)
    	{
    		for (int j = 0; j < 10; j++)
    			qDebug() << i << j;
    
    		emit new_point(qrand() % 200, qrand() % 200);
    		i++;
    	}
    
    	if (i == 10000)
    		emit finished();
    	else
    		emit paused();
    }
    
    void Algorithm::setRunning(bool value)
    {
    	running = value;
    	qDebug() << "Running:" << running;
    	emit finished();
    }
    
    J 1 Reply Last reply 2 Nov 2015, 23:24
    0
    • A alogim
      2 Nov 2015, 16:44

      So, I was using QCoreApplication::processEvents() to update the UI of a QDialog, and I thought QThreads (even to familiarise with them) would have been better.
      I wrote a simple test, with a MainWindow with a unique QPushButton; pressing it, a QDialog is shown, with a qGraphicsView and two buttons, one to pause, and one to stop.
      If you don't want to read all this one, simply check my code.
      I have a class Algorithm that simulates a heavy task (a while loop, inside of which there are two things, a for loop simply printing two values and a function that randomly generates two values). Those two values are returned via a signal to the dialog, so that I can use them to draw a point on the qGraphicsView. Another signal (finished()) is emitted when the while loop ends (that is, when the conditions i < 10000 or running == true are false). Running is a private member variable of the class Algorithm. It is set to false if a user clicks on pause/stop on the dialog. So I have anothe signal, emitted by Dialog, caught by class Algorithm, that sets running to true or false.

      The problem arises since this last signal (setRunning(bool)) is always caught at the end of the loop, when the computations already are ended.
      So I added Qt::DirectConnection and this now is caught when the button is pressed.
      I wonder if there is a better way to do this.
      Thank you in advance.
      I copy here the code, if you don't want to read all the above :D

      //mainwindow.h
      #ifndef MAINWINDOW_H
      #define MAINWINDOW_H
      
      #include <QMainWindow>
      
      namespace Ui {
        class MainWindow;
      }
      
      class MainWindow : public QMainWindow
      {
        Q_OBJECT
      
        public:
          explicit MainWindow(QWidget *parent = 0);
          ~MainWindow();
      
        private slots:
      	void on_pushButton_clicked();
      
        private:
      	Ui::MainWindow *ui;
      };
      #endif // MAINWINDOW_H
      

      MainWindow.cpp

      #include "dialog.h"
      #include "mainwindow.h"
      #include "ui_mainwindow.h"
      
      #include <QThread>
      
      MainWindow::MainWindow(QWidget *parent) :
          QMainWindow(parent),
          ui(new Ui::MainWindow)
      {
        ui->setupUi(this);
      }
      
      MainWindow::~MainWindow()
      {
        delete ui;
      }
      
      void MainWindow::on_pushButton_clicked()
      {
        Dialog *d = new Dialog(this);
        d->setAttribute(Qt::WA_DeleteOnClose, true);
        d->show();
        d->doSomething();
      }
      

      dialog.h

      #ifndef DIALOG_H
      #define DIALOG_H
      
      #include "algorithm.h"
      
      #include <QDialog>
      #include <QGraphicsScene>
      #include <QThread>
      
      namespace Ui {
      	class Dialog;
      }
      
      class Dialog : public QDialog
      {
      		Q_OBJECT
      
      	public:
      		explicit Dialog(QWidget *parent = 0);
      		~Dialog();
      
      	private:
      		Ui::Dialog *ui;
      		QGraphicsScene* scene;
      		bool running;
      		int i, c;
      		Algorithm* a;
      
      	signals:
      		void setStatus(bool);
      
      	private slots:
      		void on_pushButton_clicked();
      		void on_pushButton_2_clicked();
      		void draw_point(int x, int y);
      
      	public slots:
      		void doSomething();
      };
      
      #endif // DIALOG_H
      

      dialog.cpp

      #include "algorithm.h"
      #include "dialog.h"
      #include "ui_dialog.h"
      
      #include <QDebug>
      #include <QThread>
      
      Dialog::Dialog(QWidget *parent) :
      	QDialog(parent),
      	ui(new Ui::Dialog)
      {
      	ui->setupUi(this);
      	scene = new QGraphicsScene(this);
      	scene->setSceneRect(0, 0, 200, 200);
      	ui->graphicsView->setScene(scene);
      	ui->graphicsView->setFixedSize(200, 200);
      
      	i = 0;
      	c = 0;
      
      	running = true;
      }
      
      Dialog::~Dialog()
      {
      	delete scene;
      	delete ui;
      }
      
      void Dialog::doSomething()
      {
      	if (c == 0)
      	{
      		QThread* t = new QThread;
      		a = new Algorithm(i, true);
      		a->moveToThread(t);
      		connect (a, SIGNAL(new_point(int,int)), this, SLOT(draw_point(int,int)));
      		connect (t, SIGNAL(started()), a, SLOT(compute()));
      		connect (this, SIGNAL(setStatus(bool)), a, SLOT(setRunning(bool)), Qt::DirectConnection);
      		connect (a, SIGNAL(finished()), t, SLOT(quit()));
      		connect (a, SIGNAL(finished()), a, SLOT(deleteLater()));
      		connect (t, SIGNAL(finished()), t, SLOT(deleteLater()));
      
      		connect (a, SIGNAL(paused()), t, SLOT(quit()));
      		t->start();
      	}
      	else
      	{
      		QThread* t = new QThread;
      		a->moveToThread(t);
      		connect (a, SIGNAL(new_point(int,int)), this, SLOT(draw_point(int,int)));
      		connect (t, SIGNAL(started()), a, SLOT(compute()));
      		connect (this, SIGNAL(setStatus(bool)), a, SLOT(setRunning(bool)), Qt::DirectConnection);
      		connect (a, SIGNAL(finished()), t, SLOT(quit()));
      		connect (a, SIGNAL(finished()), a, SLOT(deleteLater()));
      		connect (t, SIGNAL(finished()), t, SLOT(deleteLater()));
      
      		connect (a, SIGNAL(paused()), t, SLOT(quit()));
      		t->start();
      	}
      	c++;
      }
      
      void Dialog::on_pushButton_clicked()
      {
      	running = false;
      	ui->pushButton->setEnabled(false);
      	ui->pushButton_2->setEnabled(false);
      	emit setStatus(running);
      }
      
      void Dialog::on_pushButton_2_clicked()
      {
      	if (running)
      	{
      		running = false;
      		ui->pushButton_2->setText("Resume");
      		emit setStatus(running);
      	}
      	else
      	{
      		running = true;
      		ui->pushButton_2->setText("Pause");
      		emit setStatus(running);
      		doSomething();
      	}
      }
      
      void Dialog::draw_point(int x, int y)
      {
      	scene->addEllipse(x, y, 1.0, 1.0);
      }
      

      algorithm.h

      #ifndef ALGORITHM_H
      #define ALGORITHM_H
      
      #include <QObject>
      
      class Algorithm : public QObject
      {
      		Q_OBJECT
      	public:
      		Algorithm(const int &i, const bool& running);
      		~Algorithm();
      
      	private:
      		int i;
      		bool running;
      
      	signals:
      		void new_point(int, int);
      		void finished();
      		void paused();
      
      	public slots:
      		void setRunning(bool value);
      		void compute();
      };
      
      #endif // ALGORITHM_H
      

      algorithm.cpp

      #include "algorithm.h"
      
      #include <QDebug>
      
      Algorithm::Algorithm(const int &i, const bool &running)
      {
      	this->i = i;
      	this->running = running;
      }
      
      Algorithm::~Algorithm()
      {}
      
      void Algorithm::compute()
      {
      	while ((i < 10000) && running)
      	{
      		for (int j = 0; j < 10; j++)
      			qDebug() << i << j;
      
      		emit new_point(qrand() % 200, qrand() % 200);
      		i++;
      	}
      
      	if (i == 10000)
      		emit finished();
      	else
      		emit paused();
      }
      
      void Algorithm::setRunning(bool value)
      {
      	running = value;
      	qDebug() << "Running:" << running;
      	emit finished();
      }
      
      J Offline
      J Offline
      JKSH
      Moderators
      wrote on 2 Nov 2015, 23:24 last edited by
      #2

      @alogim said:

      So I added Qt::DirectConnection and this now is caught when the button is pressed.

      Please don't do that! That causes your your slot to run in the GUI thread instead of your Algorithm's thread.

      The problem arises since this last signal (setRunning(bool)) is always caught at the end of the loop

      That's because your long while() loop blocks the thread's event loop. When the event loop is blocked, the thread cannot process any signals.

      There are two ways to use QThread:

      1. Create a worker QObject (like your Algorithm). Transfer data from between the threads using signals and slots. Do not implement any long running while() loops or long-running functions in your worker QObject.
      2. Subclass QThread and reimplement QThread::run(). Transfer data from your GUI thread to your worker thread using mutex-protected variables (note: your QThread subclass can still emit signals). Do not implement any slots in your QThread subclass.

      Since you want to have a long-running while() loop, and you're not using signals and slots to transfer data (you only use signals to start/stop the computation), that means option #2 is more suitable for your use case.

      Furthermore, with option #2, you don't need to implement your own running member variable. Your GUI thread can just call QThread::requestInterruption(), and your while loop can query QThread::isInterruptionRequested() to check if it should break.

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      A 1 Reply Last reply 3 Nov 2015, 12:12
      1
      • J JKSH
        2 Nov 2015, 23:24

        @alogim said:

        So I added Qt::DirectConnection and this now is caught when the button is pressed.

        Please don't do that! That causes your your slot to run in the GUI thread instead of your Algorithm's thread.

        The problem arises since this last signal (setRunning(bool)) is always caught at the end of the loop

        That's because your long while() loop blocks the thread's event loop. When the event loop is blocked, the thread cannot process any signals.

        There are two ways to use QThread:

        1. Create a worker QObject (like your Algorithm). Transfer data from between the threads using signals and slots. Do not implement any long running while() loops or long-running functions in your worker QObject.
        2. Subclass QThread and reimplement QThread::run(). Transfer data from your GUI thread to your worker thread using mutex-protected variables (note: your QThread subclass can still emit signals). Do not implement any slots in your QThread subclass.

        Since you want to have a long-running while() loop, and you're not using signals and slots to transfer data (you only use signals to start/stop the computation), that means option #2 is more suitable for your use case.

        Furthermore, with option #2, you don't need to implement your own running member variable. Your GUI thread can just call QThread::requestInterruption(), and your while loop can query QThread::isInterruptionRequested() to check if it should break.

        A Offline
        A Offline
        alogim
        wrote on 3 Nov 2015, 12:12 last edited by
        #3

        @JKSH said:

        Please don't do that! That causes your your slot to run in the GUI thread instead of your Algorithm's thread.

        I knew this problem, but it seemed the only way to make it work. Anyway, as you said, it is not a valid solution, it was just a test.

        1. Subclass QThread and reimplement QThread::run(). Transfer data from your GUI thread to your worker thread using mutex-protected variables (note: your QThread subclass can still emit signals). Do not implement any slots in your QThread subclass.

        Since you want to have a long-running while() loop, and you're not using signals and slots to transfer data (you only use signals to start/stop the computation), that means option #2 is more suitable for your use case.

        I did the following:
        dialog.h

        #ifndef DIALOG_H
        #define DIALOG_H
        
        #include <QDialog>
        #include <QGraphicsScene>
        #include "algorithm.h"
        
        namespace Ui {
        	class Dialog;
        }
        
        class Dialog : public QDialog
        {
        		Q_OBJECT
        
        	public:
        		explicit Dialog(QWidget *parent = 0);
        		~Dialog();
        
        	private:
        		Ui::Dialog *ui;
        		QGraphicsScene* scene;
        		algorithm* a;
        
        	public slots:
        		void draw_new_point(int x, int y);
        	private slots:
        		void on_pushButton_clicked();
        		void on_pushButton_2_clicked();
        };
        
        #endif // DIALOG_H
        

        dialog.cpp

        #include "dialog.h"
        #include "ui_dialog.h"
        
        Dialog::Dialog(QWidget *parent) :
        	QDialog(parent),
        	ui(new Ui::Dialog)
        {
        	ui->setupUi(this);
        	scene = new QGraphicsScene(this);
        	scene->setSceneRect(0, 0, 300, 300);
        	ui->graphicsView->setScene(scene);
        	ui->graphicsView->setFixedSize(300, 300);
        
        	a = NULL;
        }
        
        Dialog::~Dialog()
        {
        	delete scene;
        	delete ui;
        }
        
        void Dialog::draw_new_point(int x, int y)
        {
        	scene->addEllipse(x, y, 1.0, 1.0);
        }
        
        void Dialog::on_pushButton_clicked()
        {
        	a = new algorithm;
        
        	connect (a, SIGNAL(new_point(int,int)), this, SLOT(draw_new_point(int,int)));
        	connect (a, SIGNAL(finished()), a, SLOT(quit()));
        	connect (a, SIGNAL(finished()), a, SLOT(deleteLater()));
        
        	a->start();
        }
        
        void Dialog::on_pushButton_2_clicked()
        {
        	a->requestInterruption();
        }
        

        algorithm.h

        #ifndef ALGORITHM_H
        #define ALGORITHM_H
        
        #include <QThread>
        #include "algorithm.h"
        
        class algorithm : public QThread
        {
        		Q_OBJECT
        
        	public:
        		algorithm();
        
        		// QThread interface
        	protected:
        		void run();
        
        	signals:
        		void new_point(int, int);
        
        };
        
        #endif // ALGORITHM_H
        

        algorithm.cpp

        #include "algorithm.h"
        #include "unistd.h"
        
        algorithm::algorithm()
        {
        
        }
        
        void algorithm::run()
        {
        	for (int i = 0; i < 10000; i++)
        	{
        		if (isInterruptionRequested())
        			break;
        		emit new_point(qrand() % 300, qrand() % 300);
        	}
        }
        

        But still the graphicsView is not smoothly updated, but in blocks. If I add usleep(100000) after the break in the statement, everything works as expected, with qGraphicsView updating smoothly.

        J 1 Reply Last reply 3 Nov 2015, 12:31
        0
        • A alogim
          3 Nov 2015, 12:12

          @JKSH said:

          Please don't do that! That causes your your slot to run in the GUI thread instead of your Algorithm's thread.

          I knew this problem, but it seemed the only way to make it work. Anyway, as you said, it is not a valid solution, it was just a test.

          1. Subclass QThread and reimplement QThread::run(). Transfer data from your GUI thread to your worker thread using mutex-protected variables (note: your QThread subclass can still emit signals). Do not implement any slots in your QThread subclass.

          Since you want to have a long-running while() loop, and you're not using signals and slots to transfer data (you only use signals to start/stop the computation), that means option #2 is more suitable for your use case.

          I did the following:
          dialog.h

          #ifndef DIALOG_H
          #define DIALOG_H
          
          #include <QDialog>
          #include <QGraphicsScene>
          #include "algorithm.h"
          
          namespace Ui {
          	class Dialog;
          }
          
          class Dialog : public QDialog
          {
          		Q_OBJECT
          
          	public:
          		explicit Dialog(QWidget *parent = 0);
          		~Dialog();
          
          	private:
          		Ui::Dialog *ui;
          		QGraphicsScene* scene;
          		algorithm* a;
          
          	public slots:
          		void draw_new_point(int x, int y);
          	private slots:
          		void on_pushButton_clicked();
          		void on_pushButton_2_clicked();
          };
          
          #endif // DIALOG_H
          

          dialog.cpp

          #include "dialog.h"
          #include "ui_dialog.h"
          
          Dialog::Dialog(QWidget *parent) :
          	QDialog(parent),
          	ui(new Ui::Dialog)
          {
          	ui->setupUi(this);
          	scene = new QGraphicsScene(this);
          	scene->setSceneRect(0, 0, 300, 300);
          	ui->graphicsView->setScene(scene);
          	ui->graphicsView->setFixedSize(300, 300);
          
          	a = NULL;
          }
          
          Dialog::~Dialog()
          {
          	delete scene;
          	delete ui;
          }
          
          void Dialog::draw_new_point(int x, int y)
          {
          	scene->addEllipse(x, y, 1.0, 1.0);
          }
          
          void Dialog::on_pushButton_clicked()
          {
          	a = new algorithm;
          
          	connect (a, SIGNAL(new_point(int,int)), this, SLOT(draw_new_point(int,int)));
          	connect (a, SIGNAL(finished()), a, SLOT(quit()));
          	connect (a, SIGNAL(finished()), a, SLOT(deleteLater()));
          
          	a->start();
          }
          
          void Dialog::on_pushButton_2_clicked()
          {
          	a->requestInterruption();
          }
          

          algorithm.h

          #ifndef ALGORITHM_H
          #define ALGORITHM_H
          
          #include <QThread>
          #include "algorithm.h"
          
          class algorithm : public QThread
          {
          		Q_OBJECT
          
          	public:
          		algorithm();
          
          		// QThread interface
          	protected:
          		void run();
          
          	signals:
          		void new_point(int, int);
          
          };
          
          #endif // ALGORITHM_H
          

          algorithm.cpp

          #include "algorithm.h"
          #include "unistd.h"
          
          algorithm::algorithm()
          {
          
          }
          
          void algorithm::run()
          {
          	for (int i = 0; i < 10000; i++)
          	{
          		if (isInterruptionRequested())
          			break;
          		emit new_point(qrand() % 300, qrand() % 300);
          	}
          }
          

          But still the graphicsView is not smoothly updated, but in blocks. If I add usleep(100000) after the break in the statement, everything works as expected, with qGraphicsView updating smoothly.

          J Offline
          J Offline
          JKSH
          Moderators
          wrote on 3 Nov 2015, 12:31 last edited by
          #4

          @alogim said:

          But still the graphicsView is not smoothly updated, but in blocks. If I add usleep(100000) after the break in the statement, everything works as expected, with qGraphicsView updating smoothly.

          If you don't have usleep(), then you will spam your GUI thread with lots and lots of signals in a very short amount of time. The GUI thread can't keep up, that's why if becomes non-smooth.

          Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

          A 1 Reply Last reply 3 Nov 2015, 13:17
          0
          • J JKSH
            3 Nov 2015, 12:31

            @alogim said:

            But still the graphicsView is not smoothly updated, but in blocks. If I add usleep(100000) after the break in the statement, everything works as expected, with qGraphicsView updating smoothly.

            If you don't have usleep(), then you will spam your GUI thread with lots and lots of signals in a very short amount of time. The GUI thread can't keep up, that's why if becomes non-smooth.

            A Offline
            A Offline
            alogim
            wrote on 3 Nov 2015, 13:17 last edited by alogim 11 Mar 2015, 13:18
            #5

            @JKSH said:

            @alogim said:

            But still the graphicsView is not smoothly updated, but in blocks. If I add usleep(100000) after the break in the statement, everything works as expected, with qGraphicsView updating smoothly.

            If you don't have usleep(), then you will spam your GUI thread with lots and lots of signals in a very short amount of time. The GUI thread can't keep up, that's why if becomes non-smooth.

            Yes, that seems to be a good explanation but... why, if I put the same loop (without usleep() in the dialog class and call processEvents() after each item addition (without using threads at all), does the qGraphicsView smoothly update?

            J 1 Reply Last reply 3 Nov 2015, 13:31
            0
            • A alogim
              3 Nov 2015, 13:17

              @JKSH said:

              @alogim said:

              But still the graphicsView is not smoothly updated, but in blocks. If I add usleep(100000) after the break in the statement, everything works as expected, with qGraphicsView updating smoothly.

              If you don't have usleep(), then you will spam your GUI thread with lots and lots of signals in a very short amount of time. The GUI thread can't keep up, that's why if becomes non-smooth.

              Yes, that seems to be a good explanation but... why, if I put the same loop (without usleep() in the dialog class and call processEvents() after each item addition (without using threads at all), does the qGraphicsView smoothly update?

              J Offline
              J Offline
              JKSH
              Moderators
              wrote on 3 Nov 2015, 13:31 last edited by
              #6

              @alogim said:

              Yes, that seems to be a good explanation but... why, if I put the same loop (without usleep() in the dialog class and call processEvents() after each item addition (without using threads at all), does the qGraphicsView smoothly update?

              Use QElapsedTimer to find out:

              1. How long does it take to emit the signal 10000 times without processEvents()?
              2. How long does it take to emit the signal 10000 times with processEvents()?

              Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

              1 Reply Last reply
              0

              2/6

              2 Nov 2015, 23:24

              4 unread
              • Login

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