5

In QGIS 2.x I have a PyQGIS script that utilises a custom form created in Qt Designer. I could simply call the form and connect a button to a function with the following:

class MyWidget(QtGui.QWidget):
    myForm = uic.loadUi('ui_file.ui')

    def doSomething(self):
        print 'Hello World'

myWidget = MyWidget()
searchButton = myWidget.myForm.findChildren(QtGui.QWidget, 'searchButton')[0]
searchButton.pressed.connect(myWidget.doSomething)
myWidget.show()

I'm now trying to update this script for use in QGIS 3.4, which now requires processing scripts to be written by extending the QgsProcessingAlgorithm class. I've used the template script as described in the documentation, and used createCustomParametersWidget() to show my custom ui in place of the default form.

However, I can't figure out how to get the signal/slot code to work correctly. I've tried defining the signal in the createCustomParametersWidget function and in the initAlgorithm function. When the script is run, the custom form shows, but the button is not connected.

class MyTool(QgsProcessingAlgorithm):  

    INPUT = 'INPUT'
    OUTPUT = 'OUTPUT' 

   class MyWidget(QWidget):
        myForm = uic.loadUi('ui_file.ui')

        def exec_ (self):
            exec_ = self.myForm.show()

        def doSomething(self):
            print('hello World!')

    def createCustomParametersWidget(self, QWidget): 
        myWidget = self.MyWidget()
        searchButton = myWidget.myForm.findChildren(QToolButton, 'searchButton')[0] #also tried this in initAlgorithm()
        searchButton.pressed.connect(myWidget.doSomething)

It seems the initAlgorithm takes a configuration parameter (but I can't find any documentation on how to set this up, and this may not be the solution anyway).

Could anybody offer a code snippet on how to make this work in QGIS 3.4, or some links to some further information on how to the this up correctly? If possible, I want to avoid making this into a fully fledged plugin.

6
+50

I don't see the practical side of creating classes inside other classes. Just split it.

Below is how I will make your code work :

import os
from PyQt5 import uic
from PyQt5.QtWidgets import QWidget
from qgis.core import QgsProcessingAlgorithm

os.chdir("/home/julien/Bureau/")

FORM_CLASS, _ = uic.loadUiType("ui_file.ui")


class MyWidget(QWidget, FORM_CLASS):
    def __init__(self, parent=None):
        super(MyWidget, self).__init__(parent)
        self.setupUi(self)
        # signals
        self.searchButton.pressed.connect(self.doSomething)

    def doSomething(self):
        print('hello World!')


class MyTool(QgsProcessingAlgorithm):

    INPUT = 'INPUT'
    OUTPUT = 'OUTPUT'

    def createCustomParametersWidget(self): 
        self.myWidget = MyWidget()
        self.myWidget.show()


my_alg = MyTool()
my_alg.createCustomParametersWidget()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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