2

I'm actually trying to merge one of my Python program inside a QGIS 3 plugin. But I'm unable to run my simulation without freezing UI.

I tried several methods, first just calling a function on click, then I tried using QThread but only found examples for Qt4, and GUI froze again. Finally I tried to rewrite a QgsTask object following the PyQgis Cookbook.

But I always end with a frozen GUI, no matter how I write this class... I tried:

  • An object inheriting from QgsTask only which run function is calling the run() function from my simulation

  • Multiple inheritance : a class inheriting both from my Simulation object and the QgsTask object, rewrote the run() with the one from my simulation... I tested this double inheritance in a dummy class outside of gui and it is working all right, as my Simulation class.

I'm not sure but it looks like multiple mains() from QGIS and my own objects is kind of a mess. It's freezing but in facts simulation is not running and outputdir isn't created.

Here is my class:

class QGISimulationTask(QgsTask, Simulation):
    def __init__(self, params):
        desc = 'Simu ' + str(params.split()[2:5])
        Simulation.__init__(self, user_params=params, interface='qgis')
        QgsTask.__init__(self, description=desc, flags=QgsTask.CanCancel)

    def run(self):
        self.init_project()
        self.beginTime = time()
        preLog = 0
        c = 0
        for year in range(2015, self.finalYear + 1):
            ...

    def finished(self, success):
        if success:
            self.compute_results()
        else:
            QgsMessageLog.logMessage('Échec de la simulation', Qgis.Critical)

    def cancel(self):
        super(QgsTask, self).cancel()
        self.reset()
        QgsMessageLog.logMessage('Simulation annulée', Qgis.Info)

Other classes, in separated py files :

  • Ui
  • Widget inheriting Ui
  • Simulation
  • SimlationTask inheriting from QgsTask and Simulation
  • PluginClass with a start() method to create a SimulationTask object on click.

how I'm starting a task :

        self.task = QGISimlationTask(params, self.dockwidget.Simu_progressBar)
        # QgsApplication.taskManager().addTask(self.task)

Seems like it's freezing during init (before I add it to the manager...)

Any ideas ?

3 Answers 3

0

How do you start the QgsTask?

Not sure if this helps you but I´ve asked about QgsTask a couple of months ago: Usage of QgsTask and QgsTaskManager. I've implemented the QgsTask on few places in my plugin (Like here and in the end of this file)

Hope it helps!

1
  • I edited my post so you can see
    – vidlb
    Nov 23, 2018 at 19:01
0

It looks like you're directly setting a progress bars progress from the background thread. This is a big no-no in qt libraries -- you CANNOT access gui widgets from anything but the main thread.

1
  • ok I removed the progress bar the problem still remains
    – vidlb
    Nov 24, 2018 at 13:00
0

I finally found errors, it was mostly due to a bad super().____init____() and one dirty while loop (ok, my bad).

Here is a working constructor :

class QGISimulationTask(Simulation, QgsTask):
    def __init__(self, params):
        super().__init__(params, interface='qgis')
        self.desc = 'Simu ' + str(params.split()[2:5])
        super(QgsTask, self).__init__(self.desc, QgsTask.CanCancel)
        self.init_project()

I found Python's inheritance quite hard to apprehend..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.