Nous utilisons des cookies pour vous garantir la meilleure expérience sur notre site. Si vous continuez à utiliser ce dernier, nous considèrerons que vous acceptez l'utilisation des cookies. J'ai compris ! ou En savoir plus !.
banniere

Le portail francophone de la géomatique


Toujours pas inscrit ? Mot de passe oublié ?
Nom d'utilisateur    Mot de passe              Toujours pas inscrit ?   Mot de passe oublié ?

Annonce

GEODATA DAYS 2024

#1 Thu 22 December 2022 17:20

Eckmül
Participant actif
Date d'inscription: 5 Feb 2019
Messages: 50

QGIS: Plug-in Python qui ne s'execute pas

Bonjour,

J'ai commencé par développer une extension en python sur QGIS. Je suis parti de la base de "Plug-in Builder" à laquelle j'ai ajouté des fonctions créé par le modèle builder (exporter le code python à partir du modeleur). le programme python est un peu gros, du coup, je ne vais pas le copier ici, mais j'ai un petit souci qui vient sûrement de la fonction run de la fonction principale.

Code:

    def display_point(self, point):
        # report map coordinates from a canvas click
        coords = "{}, {}".format(point.x(), point.y())
        self.dlg.lineEditXYEcole.setText(str(coords))

    def montrerFenetre(self):
        self.dlg.show()

    def boutonPointer(self):
        # a reference to our map canvas
        canvas = self.iface.mapCanvas()
        # this QGIS tool emits as QgsPoint after each click on the map canvas
        self.pointTool = QgsMapToolEmitPoint(canvas)
        # cacher la fenêtre
        self.dlg.hide()

        #cliquer le point et afficher les coordonnées
        self.pointTool.canvasClicked.connect(self.display_point)
        canvas.setMapTool(self.pointTool)

        #remettre la fenêtre
        self.pointTool.canvasClicked.connect(self.montrerFenetre)

    def run(self):
        """Run method that performs all the real work"""

        # Create the dialog with elements (after translation) and keep reference
        # Only create GUI ONCE in callback, so that it will only load when the plugin is started
        if self.first_start == True:
            self.first_start = False
            self.dlg = CheminementEcoleDialog()

            # les fonctions liés aux boutons
            self.dlg.parcourirSortieCheminement.clicked.connect(self.sortieCheminements)
            self.dlg.parcourirSortieFinale.clicked.connect(self.sortieFinale)
            self.dlg.parcourirCouche.clicked.connect(self.aj_fichier_combo_box)
            self.dlg.parcourirReseauRoutier.clicked.connect(self.aj_fichier_combo_box)
            self.dlg.pointerXYEcole.clicked.connect(self.boutonPointer)

        # Fetch the currently loaded layers
        layers = QgsProject.instance().layerTreeRoot().children()
        # Clear the contents of the comboBox from previous runs
        self.dlg.selectCouche.clear()
        self.dlg.ReseauRoutierComboBox.clear()
        # Populate the comboBox with names of all the loaded layers
        self.dlg.selectCouche.addItems([layer.name() for layer in layers])
        self.dlg.ReseauRoutierComboBox.addItems([layer.name() for layer in layers])

        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:
            # traitement traité grâce aux fonctions crées par le modeleur graphique

            #coordonnées de l'école pointer
            coordonnees = self.dlg.lineEditXYEcole.text()
            xy = coordonnees.split(', ')
            pointXYEcole = QgsPointXY(float(xy[0]),float(xy[1]))

            #Reseau routier pour calculer les chemins les plus courts
            reseauRoutier = self.dlg.ReseauRoutierComboBox.currentText()

            #adresses des élèves
            adresseEleves = self.dlg.selectCouche.currentText()

            #sortie cheminement
            filename_sortie_cheminement = self.dlg.lineEditSortieCheminements.text()

            #sortie finale du fichier
            filename_sortie_finale = self.dlg.lineEditSortieFinale.text()

            parameters = {
                'coordonnescole': pointXYEcole, #point de départ
                'Rseauroutier': reseauRoutier, #réseau routier
                'AdressesEleves': adresseEleves, #adresses élèves
                'sortieCheminement' : filename_sortie_cheminement, # Chemins vers l'école
                'sortieFinale': filename_sortie_finale #sortie finale
            }

            ## traitement
            fx._nb_eleves_par_tronon.processAlgorithm(parameters=parameters)

            ## sortie de la couche cheminement
            with open(filename_sortie_cheminement, 'w') as output_file:
                selectedLayerIndex = self.dlg.selectCouche.currentIndex()
                selectedLayer = layers[selectedLayerIndex].layer()
                fieldnames = [field.name() for field in selectedLayer.fields()]
                # write header
                line = ','.join(name for name in fieldnames) + '\n'
                output_file.write(line)
                # write feature attributes
                for f in selectedLayer.getFeatures():
                    line = ','.join(str(f[name]) for name in fieldnames) + '\n'
                    output_file.write(line)

            ## sortie de la couche finale
            with open(filename_sortie_finale, 'w') as output_file:
                selectedLayerIndex = self.dlg.selectCouche.currentIndex()
                selectedLayer = layers[selectedLayerIndex].layer()
                fieldnames = [field.name() for field in selectedLayer.fields()]
                # write header
                line = ','.join(name for name in fieldnames) + '\n'
                output_file.write(line)
                # write feature attributes
                for f in selectedLayer.getFeatures():
                    line = ','.join(str(f[name]) for name in fieldnames) + '\n'
                    output_file.write(line)

            ## message de succès du programme
            self.iface.messageBar().pushMessage(
                "Success", "Cheminements calculés " + filename_sortie_finale,
                level=Qgis.Success, duration=5)

J'ai créé un bouton "pointer" qui permet de remplir un "lineEdit" avec les coordonnées pointés. et quand je clique sur bouton pointer, tout marche très bien, mais quand je clique sur Ok pour finir le programme, il a la même réaction qu'avec le bouton "pointer" : càd qu'il attend que je pointe un point, si je le fais, il me réouvre la fenêtre de l'extension. Auriez-vous une idée pour m'aider à trouver d'où vient le problème.

Hors ligne

 

#2 Thu 22 December 2022 20:57

YoLecomte
Participant assidu
Lieu: Epinal
Date d'inscription: 7 Jul 2015
Messages: 252

Re: QGIS: Plug-in Python qui ne s'execute pas

Bonjour,

Pas évident de débugguer juste en lisant vos quelques extraits de code, mais je vais faire une tentative smile.

Dans votre fonction

Code:

BoutonPointer

vous appelez

Code:

canvas.setMapTool(self.pointTool)

pour mettre en place votre pointeur.
Je pense que votre problème réside dans le fait que vous ne désactivez jamais votre mapTool. Donc lorsque vous cliquez sur Ok le traitement s'éxecute mais votre mapTool est toujours actif et appele montrerFenetre lors d'un click sur le canvas.

Ajouter la ligne suivante dans votre fonction
:

Code:

def montrerFenetre(self):
    canvas.unsetMapTool(self.pointTool)
    self.dlg.show()

Cela devrait résoudre votre problème.

Dernière modification par YoLecomte (Thu 22 December 2022 21:01)

Hors ligne

 

#3 Fri 23 December 2022 09:46

Eckmül
Participant actif
Date d'inscription: 5 Feb 2019
Messages: 50

Re: QGIS: Plug-in Python qui ne s'execute pas

Tout d'abord merci pour la première suggestion de modification.

Bon, avec cette modification le programme n'attend plus que l'on clique un point, du coup, c'est bon, mais le programme ne s’exécute pas pour autant. J'ai pensé que le programme ne passait jamais dans la boucle

Code:

if result :

du coup, j'ai affiché la valeur de result via une boîte de dialogue Qgis :

Code:

self.iface.messageBar().pushMessage("Success", "result : " + str(result),level=Qgis.Success, duration=5)

et là la valeur de result est de 0, du coup, il doit y avoir quelque chose dans le run() qui fait passer result à 0 alors qu'il devrait être à 1 pour executer les fonctions qui sont dans le run().

Si vous avez besoin d'autre éléments de mon code pour essayer de comprendre le programme, n'hésitez pas, je ferai d'autres copies.

Hors ligne

 

#4 Fri 23 December 2022 10:24

YoLecomte
Participant assidu
Lieu: Epinal
Date d'inscription: 7 Jul 2015
Messages: 252

Re: QGIS: Plug-in Python qui ne s'execute pas

La variable result devrait valoir 1 lorsque vous cliquez sur le bouton OK de votre interface (si toutefois, vous avez gardé le dialogue créé par le plugin Builder pour vous en servir de base).
Dans votre cas, self.dlg doit être un objet de type QDialog.
La ligne

Code:

result = self.dlg.exec_()

exécute cet objet et fais apparaître votre interface. Elle lance également la boucle d'événement qui rend cette interface dynamique jusqu'au moment où la fenêtre est fermée.

Normalement votre objet QDialog (contenu dans la variable dlg de votre instance de plugin (self)) doit avoir des boutons par défaut (à minima un bouton Ok et un bouton Annuler si vous n'avez rien changé).
Ces boutons par défaut permettent à PyQT (la librairie graphique de votre interface) de gérer l'événement de fermeture de votre boite de dialogue.
Si vous cliquez sur Ok, result doit valoir 1 (QDialog.accepted) sinon 0 (QDialog.rejected).

Donc si result vaut toujours 0 dans votre programme, c'est que votre interface n'est pas construite correctement.

Avez vous bien conservé les boutons par défaut de votre fenêtre de dialogue (qui a été généré par le plugin Builder)?

Impossible d'en dire plus avec les éléments que vous fournissez.

Sinon il faudra partager le zip de votre plugin ainsi que tout les éléments nécessaire pour l'utiliser.

Dernière modification par YoLecomte (Fri 23 December 2022 10:27)

Hors ligne

 

#5 Fri 23 December 2022 11:43

Eckmül
Participant actif
Date d'inscription: 5 Feb 2019
Messages: 50

Re: QGIS: Plug-in Python qui ne s'execute pas

Ok, normalement, j'ai gardé les boutons "OK et "annuler" par défaut, il n'y a aucun soucis là dessus.

Du coup s'il y a des gens courageux, je partage mon plug-in en zip.

Merci d'avance à ceux qui seront déterminer pour m'aider


Fichier(s) joint(s) :
Pour accéder aux fichiers vous devez vous inscrire.

Hors ligne

 

#6 Fri 23 December 2022 13:23

YoLecomte
Participant assidu
Lieu: Epinal
Date d'inscription: 7 Jul 2015
Messages: 252

Re: QGIS: Plug-in Python qui ne s'execute pas

le problème est situé dans la fonction montrerFenetre qui relance la boucle d'évenement sans regarder la valeur de retour.

En PJ, une version modifiée de votre plugin.

J'ai également modifié l'import de votre algorithme processing afin qu'il fonctionne sur n'importe quelle machine (pas de chemin en dur!).

Dernière modification par YoLecomte (Fri 23 December 2022 13:24)


Fichier(s) joint(s) :
Pour accéder aux fichiers vous devez vous inscrire.

Hors ligne

 

#7 Mon 09 January 2023 11:49

Eckmül
Participant actif
Date d'inscription: 5 Feb 2019
Messages: 50

Re: QGIS: Plug-in Python qui ne s'execute pas

Merci de ta réponse @Yolecomte, je reviens sur cette discussion après pas mal de temps, je n'ai plus le retour de la fenêtre grâce à ta modification, merci bien. J'essaye maintenant de voir comment il peut exécuter les fonctions que je lui dit, parce qu'il ne réagit toujours pas, cela doit toujours venir du fait qu'il a une valeur nulle dans la variable result

Hors ligne

 

#8 Mon 09 January 2023 12:27

YoLecomte
Participant assidu
Lieu: Epinal
Date d'inscription: 7 Jul 2015
Messages: 252

Re: QGIS: Plug-in Python qui ne s'execute pas

Bonjour,
si tu regardes la version modifiée du plugin dans mon message précédant, tu devrais pouvoir t'en sortir puisque j'ai justement corrigé le problème de non exécution du run().
Est ce que tu as bien repris les modifications que j'ai effectuée? Est-ce que tu les as bien comprises?

Hors ligne

 

#9 Mon 09 January 2023 14:07

Eckmül
Participant actif
Date d'inscription: 5 Feb 2019
Messages: 50

Re: QGIS: Plug-in Python qui ne s'execute pas

J'ai ouvert le nouveau fichier que tu m'as envoyé, j'ai vu que tu avais séparé l’exécution du programme dans un fonction show_dialog() exécuté à la fin  du run(), mais j'ai essayé d’exécuter le plug-in tel quel dans mon QGIS et je n'ai pas eu d’exécution du plug-in. Aucune couche ne s'est créé.

PS : Je l'ai relancé et j'ai cette fois-ci j'ai un message d'erreur, je dois renseigné un 'self', 'context' et 'model_feedback' dans la fonction processsAlgorithm()

Dernière modification par Eckmül (Mon 09 January 2023 14:18)

Hors ligne

 

#10 Mon 09 January 2023 14:22

YoLecomte
Participant assidu
Lieu: Epinal
Date d'inscription: 7 Jul 2015
Messages: 252

Re: QGIS: Plug-in Python qui ne s'execute pas

C'est bon signe, c'est que ça fonctionne. Tu n'as plus qu'à corriger toutes les erreurs que tu rencontreras.

Hors ligne

 

#11 Mon 09 January 2023 14:41

Eckmül
Participant actif
Date d'inscription: 5 Feb 2019
Messages: 50

Re: QGIS: Plug-in Python qui ne s'execute pas

En fait, je n'ai aucune idée de ce que je dois mettre comme variable dans 'model_feedback' ou 'context' et je ne trouve aucune information sur https://docs.qgis.org/3.22/en/docs/index.html

Hors ligne

 

#12 Mon 09 January 2023 15:54

YoLecomte
Participant assidu
Lieu: Epinal
Date d'inscription: 7 Jul 2015
Messages: 252

Re: QGIS: Plug-in Python qui ne s'execute pas

La il va falloir que tu fasses des recherches. Tout est accessible dans les documentations en ligne

La documentation technique est plutôt ici:
https://qgis.org/pyqgis/3.0/core/Proces … sAlgorithm

Une autre ressource qui peut être utile:
https://gis.stackexchange.com/questions … m-function

Hors ligne

 

Pied de page des forums

Powered by FluxBB