7

I have a QGIS plugin and would like to put loading GIF (spinner) somewhere in the Dialog Window. The problem is when I run the spinner with the following code and call next function, the spinner freezes and activates only when process finishes. The dialog.py looks like the following:

class DEDialog(QtWidgets.QDialog, FORM_CLASS):
  def __init__(self, parent=None):
    super(DEDialog, self).__init__(parent)
    self.setupUi(self)
    self.run_button = self.findChild(QtWidgets.QPushButton, 'pushButton')
    self.run_button.clicked.connect(self.pipeline)
    self.a = 1
    self.b = 2
    self.c = 3

def pipeline(self): self.gif = 'C:\Users\User\1474.gif' self.movie = QMovie(self.gif) self.label.setGeometry(QtCore.QRect(25, 25, 850, 850)) self.label.setMinimumSize(QtCore.QSize(200, 200)) self.movie.setCacheMode(QMovie.CacheAll) self.label.setMovie(self.movie) self.movie.start()

self.do()

def do(self): self.do_ground = FunctionFromFile(self.a, self.b, self.c)

I know that there is something like multithreading but I still don't understand how to realise it with PyQt5 correctly.

UPD. Now I have the following code, which is actually works not as I want:

    class DEDialog(QtWidgets.QDialog, FORM_CLASS):
      def __init__(self, parent=None):
        """Constructor."""
        super(DEDialog, self).__init__(parent)
        self.run_button = self.findChild(QtWidgets.QPushButton, 'pushButton')
        self.run_button.clicked.connect(self.pipeline)
def show_movie(self, task):
    self.gif = 'C:\\Users\\User\\Downloads\\1474.gif'
    self.movie = QMovie(self.gif)
    self.label.setGeometry(QtCore.QRect(25, 25, 850, 850))
    self.label.setMinimumSize(QtCore.QSize(200, 200))
    self.label.setMovie(self.movie)
    self.movie.start()
    return 5

def pipeline(self):
    mgr = QgsTaskManager()
    task = QgsTask.fromFunction('my_task', self.show_movie,
                                on_finished=calculation_finished)
    mgr.addTask(task)
    print("added movie")

    task1 = QgsTask.fromFunction('my_task1', calculate,
                                on_finished=calculation_finished)
    mgr.addTask(task1)
    print("added task")

def calculate(task): return 5 * 6

def calculation_finished(exception, value=None): if not exception: print( 'the magic number is {}'.format(value)) else: print( str(exception))

The problem is that I have to do countings after adding .addTask or the task will be cancelled. Another problem is that task will start only after main program in the pipeline finishes and I want to make them parallel.

1 Answers1

1

The task manager must be returned from QgsApplication.taskManager() function.

So in the function called pipeline you should do this.

def pipeline(self):
    # mgr = QgsTaskManager()
    mgr = QgsApplication.taskManager() # get the task manager
    task = QgsTask.fromFunction('my_task', self.show_movie,
                                on_finished=calculation_finished)
    mgr.addTask(task)
    print("added movie")
    task1 = QgsTask.fromFunction('my_task1', calculate,
                                on_finished=calculation_finished)
    mgr.addTask(task1)
    print("added task")

This could also be done with the python threading module. Here you can find some useful posts:

Mayo
  • 3,902
  • 3
  • 22