IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Problème de séquencement d'objets de classes


Sujet :

Python

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Ingénieur géologue
    Inscrit en
    Avril 2019
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur géologue
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2019
    Messages : 12
    Points : 5
    Points
    5
    Par défaut Problème de séquencement d'objets de classes
    Bonjour,
    Je travaille sous QGIS 3 avec Pyhon. La question que je pose doit être la même sans QGis, dans un environnement Python seul.
    En résumé, j'utilise deux classes: une première est une fenêtre PyQt5 (class QWindow(QMainWindow)) demandant le nom d'une commune. La seconde est une classe class RechercheCommune(): recherchant cette commune dans le SIG QGis.
    Pardonnez-moi le programme qui n'est pas entièrement terminé.
    Mon problème est que la seconde classe (recherche commune) est lancée sans attendre le résultat de la classe précédente.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        mw = QWindow()                               # QWindow() est une classe
        print("après mw = QWindow()")
        communeRecherchee = mw.textbox.text()
        rc = RechercheCommune()                     # RechercheCommune() est une classe
        rc.rechercheCommune(communeRecherchee)
    Je pense que la solution est toute simple et qu'une commande doit être écrite pour que le programme attende le résultat des commandes antérieures avant de continuer.
    Le programme entier est le suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    import sys
    from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QMenu, QPushButton, QLabel
    from PyQt5.QtGui import QIcon
    # from PyQt5.QtCore import pyqtSlot
     
    class QWindow(QMainWindow):
     
        def __init__(self):
            super().__init__()
            self.createMenusHorizontaux()
            self.initUI()
            self.createStatusBar()
     
        def initUI(self):
            self.modificationParametresWindow(200, 300, 400, 250, 'titre')
            self.modificationParametresToolTips()
     
            # création d'un bouton
            btn1 = self.createButton("sortie", self.width-125, self.height-30, "tooltip btn1", self.on_click)
            btn1.setToolTip('lg=120, haut=15, x=100, y=70, désactivé')
            btn1.resize(120,20)
            # btn1.clicked.connect(self.on_click)
     
            self.creationLabel ("<font color=#4400FF size='3'><b>Commune à rechercher:</b>", 10, 50, 300, 15)
            self.creationTextBox (150, 50, 150, 20)
     
            # self.getText()
            self.show()
     
        def modificationParametresWindow(self, x, y, l, h, titre):
            self.title = titre
            self.left = x
            self.top = y
            self.width = l
            self.height = h
            self.setWindowTitle(titre)
            self.setGeometry(self.left, self.top, self.width, self.height)
     
        def modificationParametresToolTips(self):
            # modification des paramètres des tooltips
            QToolTip.setFont(QFont('SansSerif', 9))                                                        # Cette méthode statique définit une police utilisée pour rendre les info-bulles.
            couleurFondToolTips = QToolTip.palette();
            couleurFondToolTips.setColor(QPalette.ToolTipBase,QColor("#FFdddd"));                                       # 
            couleurFondToolTips.setColor(QPalette.ToolTipText,QColor("#000000"));                                       # 
            QToolTip.setPalette(couleurFondToolTips)
     
        def createStatusBar(self):
            sb = QStatusBar()
            sb.setFixedHeight(18)
            self.setStatusBar(sb)
            self.statusBar().showMessage(self.tr("Ready"))
     
        def createMenusHorizontaux(self):
            # <a href="https://www.tutorialspoint.com/pyqt/qmenubar_qmenu_qaction_widgets.htm" target="_blank">https://www.tutorialspoint.com/pyqt/...on_widgets.htm</a>
            # la classe QMenuBar possède les méthodes suivantes : addMenu(), addAction(), setEnabled(), addSeperator(), Clear(), setShortcut(), setText(), setTitle(), 
            bar = self.menuBar()                                                                             # création d'un menu en haut d'écran; menuBar() est une méthode de la classe QMenuBar
            file = bar.addMenu("&File")
            file.addAction("New")
            save = QAction("Save",self)
            save.setShortcut("Ctrl+S")
            file.addAction(save)
            edit = file.addMenu("Edit")
            edit.addAction("copy")
            edit.addAction("paste")
            quit = QAction("Quit",self) 
            file.addAction(quit)
            file.triggered[QAction].connect(self.processtrigger)
            self.helpMenu = self.menuBar().addMenu(self.tr("&Help"))
    #        self.helpMenu.addAction(self.aboutAct)
    #        self.helpMenu.addAction(self.aboutQtAct)
            bar.setStyleSheet("QMenuBar::item { color: rgb(0, 0, 0); }")
     
        def createButton(self, text, x, y, toolTip, member=None):
            bouton = QPushButton(text, self)
            bouton.setToolTip(text)
            bouton.move(x,y)
            if (member != None) : bouton.clicked.connect(member);
            return bouton
     
        def creationLabel (self, text, x, y, l, h):
            self.libelle = QLabel(self)
            self.libelle.setText(text)
            #self.libelle.setAlignment(Qt.AlignCenter)
            self.libelle.move(x,y)
            #self.libelle.adjustSize()
            self.libelle.resize(300, 15)
     
        def getText(self):
            text, okPressed = QInputDialog.getText(self, "Get text","Your name:", QLineEdit.Normal, "")
            if okPressed and text != '':
                print(text)
     
        def creationTextBox (self, x, y, l, h):
            self.textbox = QLineEdit(self)
            self.textbox.move(x, y)
            self.textbox.resize(l,h)
     
     
        def processtrigger(self,q):
            print (q.text()+" is triggered")
            if (q.text() == "Quit"): self.close();
     
     
        @pyqtSlot()
        def on_click(self):
            print('PyQt5 button click')
            textboxValue = self.textbox.text()
            QMessageBox.question(self, 'Message - pythonspot.com', "You typed: " + textboxValue, QMessageBox.Ok, QMessageBox.Ok)
            # self.textbox.setText("")
            self.close()
    # fin class App(QWidget):
     
     
     
     
    class RechercheCommune():
        def __init__(self):
            self.nomFichierCommune = "D:/_Informatique/011_QGis/_QGis_donnees/_QGis_couches/_Administratif/communes.shp"
            self.aliasFichierCommune = "communes"
            self.chargementCouche()
            self.rechercheCommune("Ponteilla")
     
        def chargementCouche(self):
            # la couche est-elle déjà chargée?
            bCoucheCommunesDejaChargee = False
            for l in QgsProject.instance().mapLayers().values():                                            #iface.mapCanvas().layers():
                # print ("l.name()=", l.name(), l.source())
                # print(l.source())
                if (l.source().find("communes") >=0):
                    bCoucheCommunesDejaChargee = True
            if (bCoucheCommunesDejaChargee == False):
                # la couche n'est pas encore chargée
                # self.layerCommunes = iface.addVectorLayer(self.nomFichierCommune, self.aliasFichierCommune, "ogr")
                iface.addVectorLayer(self.nomFichierCommune, self.aliasFichierCommune, "ogr")
                print("couche communes créée")
            else:
                print("couche déjà présente")
                # self.layerCommunes = iface.setActiveLayer(QgsProject.instance().mapLayersByName('communes')[0])
     
            # la couche 'communes' est rendue active
            iface.setActiveLayer(QgsProject.instance().mapLayersByName('communes')[0])
            self.layerCommunes = iface.activeLayer()
            print("la couche 'communes' est rendue active")
            # type de symbologie de la couche
            renderer = self.layerCommunes.renderer()
            # print("Type:", renderer.type())                                                               # ['nullSymbol', 'singleSymbol', 'categorizedSymbol', 'graduatedSymbol', 'RuleRenderer', ...]
            # on change le remplissage des communes (jaune pâle, avec transparence)
            #symbols = self.layerCommunes.renderer().symbols(QgsRenderContext());                            # print(symbols)
            #symbols[0].setColor(QColor.fromRgb(0,255,0, 80))
            layerRenderer = self.layerCommunes.renderer()	# modif fond, et bordure
            mySymbol1 = QgsFillSymbol.createSimple({'color':'#00ff00', 'color_border':'#ff0000', 'width_border':'0.5'})
            layerRenderer.setSymbol (mySymbol1)
     
            self.layerCommunes.triggerRepaint()
     
        def rechercheCommune(self, nomCommune):
            # on parcours les 'features' de la couche pour y trouver la commune souhaitée
            print("...rechercheCommune...self.layerCommunes.name()=", self.layerCommunes.name())
            self.layerCommunes.selectByExpression("nom ILIKE \'" + nomCommune + "\'", QgsVectorLayer.SetSelection)
            iface.mapCanvas().zoomToSelected()
            scale = iface.mapCanvas().scale()
            scale = 120000  # int(int(scale)*2000)/1000
            iface.mapCanvas().zoomScale(scale)
     
     
     
     
     
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        mw = QWindow()
        sys.exit(app.exec_())
    else:
        mw = QWindow()
        print("après mw = QWindow()")
        communeRecherchee = mw.textbox.text()
        rc = RechercheCommune()
        # rc.rechercheCommune("Arles")
        rc.rechercheCommune(communeRecherchee)
    Merci pour votre aide

    Le copier/coller du programme a enlevé la tabulation primordiale pour python.
    Malheureusement, je ne connais pas le remède.

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    Citation Envoyé par BrDep Voir le message
    Mon problème est que la seconde classe (recherche commune) est lancée sans attendre le résultat de la classe précédente.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        mw = QWindow()                               # QWindow() est une classe
        print("après mw = QWindow()")
        communeRecherchee = mw.textbox.text()
        rc = RechercheCommune()                     # RechercheCommune() est une classe
        rc.rechercheCommune(communeRecherchee)
    Je pense que la solution est toute simple et qu'une commande doit être écrite pour que le programme attende le résultat des commandes antérieures avant de continuer.
    C'est le fonctionnement normal d'une interface graphique: mw = QWindow() démarre l'interface, l'instruction suivante app.exec_() démarre l'attente des évènements qui vont déclencher des callbacks et modifier l'état des objets de l'application.
    Dit autrement, l'instruction communeRecherchee = mw.textbox.text() s'exécute avant même que l'utilisateur ait pu faire quoi que ce soit.

    Difficile de modifier la mécanique d'un code sans comprendre comment elle est construite.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Ingénieur géologue
    Inscrit en
    Avril 2019
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur géologue
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2019
    Messages : 12
    Points : 5
    Points
    5
    Par défaut
    Merci pour vos aides.
    J'ai édulcoré le programme en éliminant les fonctions du SIG Qgis pour ne garder que du Python et le PyQt5.
    Le programme sera plus facilement compréhensible.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
     
    import sys
    from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QMenu, QPushButton, QLabel
     
    class QWindow(QMainWindow):
        def __init__(self):
            super().__init__()
            self.initUI()
     
        def initUI(self):
            self.modificationParametresWindow(200, 300, 400, 250, 'titre')
            self.creationBouton("ok", self.width-35, 50, 30, 20, "tooltip btn", self.on_click)
            self.creationLabel ("Commune à rechercher:", 10, 50, 300, 15)
            self.creationTextBox (150, 50, 150, 20)
            self.show()
     
        def modificationParametresWindow(self, x, y, l, h, titre):
            self.title = titre
            self.left = x
            self.top = y
            self.width = l
            self.height = h
            self.setWindowTitle(titre)
            self.setGeometry(self.left, self.top, self.width, self.height)
     
        def creationBouton(self, text, x, y, l, h, toolTip, member=None):
            self.bouton = QPushButton(text, self)
            self.bouton.setToolTip(text)
            self.bouton.move(x,y)
            self.bouton.resize(l, h)
            if (member != None) : self.bouton.clicked.connect(member);
     
        def creationLabel (self, text, x, y, l, h):
            self.libelle = QLabel(self)
            self.libelle.setText(text)
            self.libelle.move(x,y)
            self.libelle.resize(l, h)
     
        def creationTextBox (self, x, y, l, h):
            self.textbox = QLineEdit(self)
            self.textbox.move(x, y)
            self.textbox.resize(l,h)
     
        @pyqtSlot()
        def on_click(self):
            textboxValue = self.textbox.text()
            self.close()
    # fin class App(QWidget):
     
     
     
    class RechercheCommune():
        def __init__(self):
            print("classe RechercheCommune()")
     
        def rechercheCommune(self, nomCommune):
            print("nomCommune=", nomCommune)
    # fin class RechercheCommune()
     
     
     
     
    mw = QWindow()                          # instanciation de la classe
    communeRecherchee = mw.textbox.text()   # Récupération de la valeur entrée dans la TexBox de la classe QWindow
    rc = RechercheCommune()                 # instanciation de la classe
    rc.rechercheCommune(communeRecherchee)
    Donc mon problème est que les instructions rc = RechercheCommune() et rc.rechercheCommune(communeRecherchee) sont exécutées immédiatement et le nom de la commune entré dans la TexBox n'est pas pris en compte

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    Citation Envoyé par BrDep Voir le message
    Donc mon problème est que les instructions rc = RechercheCommune() et rc.rechercheCommune(communeRecherchee) sont exécutées immédiatement et le nom de la commune entré dans la TexBox n'est pas pris en compte
    Sûr qu'avec la mise en forme, c'est bien plus lisible...

    Mais çà ne change pas le problème: vous voulez un fonctionnement séquentiel alors que le GUI vous impose un fonctionnement évènementiel: impossible!

    Comme c'est la base du fonctionnement de n'importe quel GUI, la solution sera d'ouvrir un tuto. et apprendre à programmer avec.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Ingénieur géologue
    Inscrit en
    Avril 2019
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur géologue
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2019
    Messages : 12
    Points : 5
    Points
    5
    Par défaut ok sur le principe
    Je comprends que vous essayez de faire trouver la solution par nous-mêmes.
    Je suis persuadé que la solution est très simple et que n'importe quel programmateur la trouverait...et la donnerait.
    D'après vous je dois compulser tous les tutos sur les GUI et trouver celui qui convient.
    Pour moi, l'aide serait plutôt de me donner la solution ou de me donner les éléments pour qu'en une heure je puisse résoudre ce problème qui me bloque et, si possible, de me donner les liens des meilleurs tutos.
    Souhaitez-moi bon courage pour les semaines à venir...
    Cordialement,

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    Citation Envoyé par BrDep Voir le message
    Pour moi, l'aide serait plutôt de me donner la solution ou de me donner les éléments pour qu'en une heure je puisse résoudre ce problème qui me bloque
    Tel que vous posez le problème, il n'y a pas de solution.
    Pour le comprendre, il faut avoir appris comment fonctionne un GUI.

    Citation Envoyé par BrDep Voir le message
    et, si possible, de me donner les liens des meilleurs tutos.
    Un tuto. sera "bon" s'il prend en compte votre niveau, vos attentes,... et s'il est rédigé sous une forme suffisamment attractive pour vous donner envie d'apprendre (faire les exercices pour comprendre).
    Difficile de chercher pour vous dans la liste de ce remontera n'importe quel moteur de recherche.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Ingénieur géologue
    Inscrit en
    Avril 2019
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur géologue
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2019
    Messages : 12
    Points : 5
    Points
    5
    Par défaut alea jacta est
    Je pense que l'on tourne en rond.
    Contrairement à ce que vous pensez, il y a une solution.
    Sachez que mon métier est géologue et non informaticien. Je ne peux me permettre de passer des heures sur un petit problème comme celui-ci.
    Merci tout de même.
    Je vais tester un autre forum.
    Cordialement,

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par BrDep Voir le message
    J'ai édulcoré le programme en éliminant les fonctions du SIG Qgis pour ne garder que du Python et le PyQt5.
    Le programme sera plus facilement compréhensible.
    C'est un peu mieux. Toutefois il te faut aussi inclure PyQt5.QtCore pour pouvoir utiliser les pyqtSlot. Et comme il manque un QApplication, ton programme reste non testable. Or tu dois quand-même arriver ici avec un programme exécutable et que tu as testé toi-même.

    Accessoirement sais-tu qu'il y a une sous-partie du forum Python dédiée à PyQt ??? C'est pas que tu trouveras pas de réponse ici, mais t'auras plus de chances de trouver des connaisseurs PyQt là bas plutôt qu'ici.

    Citation Envoyé par BrDep Voir le message
    Donc mon problème est que les instructions rc = RechercheCommune() et rc.rechercheCommune(communeRecherchee) sont exécutées immédiatement et le nom de la commune entré dans la TexBox n'est pas pris en compte
    wiztricks a expliqué le souci. Tu ne peux pas demander du séquentiel dans une boucle évènementielle.
    Tu dois relier un signal de ta QLineEdit (je pense qu'un editingFinished serait un bon candidat) à un slot qui effectuera la recherche de ta commune et qui placera le résultat dans un QWidget adéquat.


    Citation Envoyé par BrDep Voir le message
    D'après vous je dois compulser tous les tutos sur les GUI et trouver celui qui convient.
    Ben c'est sûr que lire un tuto Qt serait un plus. Qt c'est pas un truc qu'on peut apprendre comme ça. Quand je m'y suis mis, j'ai carrément acheté un livre car à l'époque il n'y avait pas foule de tutos gratuits sur le net.

    Citation Envoyé par BrDep Voir le message
    Pour moi, l'aide serait plutôt de me donner la solution ou de me donner les éléments pour qu'en une heure je puisse résoudre ce problème qui me bloque et, si possible, de me donner les liens des meilleurs tutos.
    https://qt.developpez.com/tutoriels/. Ok ils sont pour Qt4 mais une fois qu'on a compris les bases, passer à Qt5 est assez facile (d'autant plus que Qt5 accepte l'ancienne syntaxe Qt4).
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Futur Membre du Club
    Homme Profil pro
    Ingénieur géologue
    Inscrit en
    Avril 2019
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur géologue
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2019
    Messages : 12
    Points : 5
    Points
    5
    Par défaut Merci Sve@r,
    Plus que merci Sve@r car tu as pris de ton temps pour répondre avec des éléments concrets qui permettent d'avancer.
    D'abord, désolé pour ce retard. J'étais en déplacement.
    Entre temps, j'avais trouvé une solution mais qui ne me plaisait pas car non facilement compréhensible. Du style:
    1) objet de classe QMainWindow avec un objet QLineEdit.
    2) en sortie (enter ou bouton cliqué), événement on_click
    3) à l'intérieur, instanciation d'un objet de la classe RechercheCommune()
    4) appel à la fonction spécifique de récupération de la commune.

    Le code (parties importantes) est le suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    class QWindow(QMainWindow):
        .......
        def on_click(self):
            textboxValue = self.textbox.text()
            rc = RechercheCommune()                 # instanciation de la classe RechercheCommune()
            rc.rechercheCommune(self.textbox.text()) # récupération de la commune dans la layer
            self.close()
    # fin class QWindow(QMainWindow):
    
    class RechercheCommune():
        def __init__(self):
            .....
        def chargementCouche(self):
            .....
        def rechercheCommune(self, nomCommune):
            .....
    # fin class
    Ce sont les deux lignes en rouge qui fonctionnent mais qui me gênent.
    J'aurais aimé que les 2 classes ne contiennent pas d'éléments de l'autre classe afin d'avoir un programme clean.
    Je modifierai sans doute ceci à l'avenir avec le temps, au fil de la maîtrise de PyQt5 et PyQGis.

    Pour les imports, ils sont natifs dans QGis et ne sont pas nécessaires. Je conviens toutefois qu'il faut prendre de bonnes habitudes et les inclure.

    Enfin. Comment fais-je pour me connecter sur le forum PyQt5?

    Cordialement,

  10. #10
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par BrDep Voir le message
    Le code (parties importantes) est le suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    class QWindow(QMainWindow):
        .......
        def on_click(self):
            textboxValue = self.textbox.text()
            rc = RechercheCommune()                 # instanciation de la classe RechercheCommune()
            rc.rechercheCommune(self.textbox.text()) # récupération de la commune dans la layer
            self.close()
    # fin class QWindow(QMainWindow):
    
    class RechercheCommune():
        def __init__(self):
            .....
        def chargementCouche(self):
            .....
        def rechercheCommune(self, nomCommune):
            .....
    # fin class
    Ce sont les deux lignes en rouge qui fonctionnent mais qui me gênent.
    J'aurais aimé que les 2 classes ne contiennent pas d'éléments de l'autre classe afin d'avoir un programme clean.
    Malheureusement, si une classe A doit à un moment ou à un autre récupérer des infos d'une classe B, alors elle est obligée d'avoir une main sur B. Toutefois ce qui est dommage, c'est d'instancier dans le slot car quand le slot se termine, ses variables locales disparaissent. Bon ici c'est pas grave car la fenêtre se ferme donc le "on_click" n'est exécuté qu'une fois mais c'est pour plus tard.

    Perso je partirais ainsi
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class QWindow(QMainWindow):
    	def __init__(self, *args, **kwargs):
    		super().__init__(*args, **kwargs)
    		self.__rc=RechercheCommune()                 # instanciation unique de la classe RechercheCommune()
    	# __init__()
    	.......
     
            @pyslot(bool)
    	def on_click(self, state):
    		self.__rc.rechercheCommune(self.textbox.text()) # récupération de la commune dans la layer
    	# on_click()
    # class QWindow
    Voilà. Tout est déclaré dans le __init__() ce qui est une bonne préconisation quand on veut être clean. Et (là encore pour être clean) j'ai défini le on_click représentant exactement ce qu'il reçoit (il reçoit aussi l'état du bouton cliqué)

    Ou alors double héritage. C'est dangereux avec PyQt mais c'est possible si on ne fait pas hériter de deux objets PyQt différents
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class QWindow(QMainWindow, RechercheCommune):
    	def __init__(self, *args, **kwargs):
    		super().__init__(*args, **kwargs)
     
    	# __init__()
    	.......
     
            @pyslot(bool)
    	def on_click(self, state):
    		self.rechercheCommune(self.textbox.text()) # récupération de la commune dans la layer
    	# on_click()
    # class QWindow
    Un peu osé mais pourquoi pas...


    Ensuite on peut discuter de mettre le self.close() dans le "on_click()" car je ne sais pas si c'est bien. Mais comme on a le droit de connecter un même signal à plusieurs slots moi j'en profiterais. Donc ton bouton pourrait être défini ainsi
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    btn=QPushButton(...)
    btn.clicked.connect(self.on_click)
    btn.clicked.connect(self.close)

    Et pour info t'as possibilité de surcharger closeEvent() qui est un slot automatiquement appelé quand la fenêtre se ferme. Ce qui te permet de rajouter un choix ultime style "vous voulez vraiment quitter ?"
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def closeEvent(self, event):
    	super().closeEvent(event)
    	event.accept()\
    		if QMessageBox.question(
    			self,
    			"Confirmation",
    			"Confirmez-vous vouloir quitter ?",
    			QMessageBox.Yes|QMessageBox.No,
    		) == QMessageBox.Yes\
    		else event.ignore()
    # closeEvent()

    Citation Envoyé par BrDep Voir le message
    Pour les imports, ils sont natifs dans QGis et ne sont pas nécessaires. Je conviens toutefois qu'il faut prendre de bonnes habitudes et les inclure.
    Oui mais comme j'ai testé sans QGis, j'avais pas les import.

    Citation Envoyé par BrDep Voir le message
    Enfin. Comment fais-je pour me connecter sur le forum PyQt5?
    Nom : Sans titre.jpg
Affichages : 93
Taille : 282,2 Ko
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  11. #11
    Futur Membre du Club
    Homme Profil pro
    Ingénieur géologue
    Inscrit en
    Avril 2019
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur géologue
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2019
    Messages : 12
    Points : 5
    Points
    5
    Par défaut Excellent!
    Merci Sve@r pour toutes ces infos,

    1) ok pour mettre l'instanciation de la seconde classe dans le __init__ de QMainWindow,
    2) ok également pour mettre la sortie du programme dans le bouton, en parallèle avec le on_click()
    3) enfin ok pour la surcharge de closeEvent()
    4) pour la surcharge de class QWindow(QMainWindow, RechercheCommune):, je n'ai pas encore le niveau et, honnêtement, je ne comprends pas tout.

    Je vais jeter un oeil sur le forum PyQt.

    Bon WE,

  12. #12
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par BrDep Voir le message
    4) pour la surcharge de class QWindow(QMainWindow, RechercheCommune):, je n'ai pas encore le niveau et, honnêtement, je ne comprends pas tout.
    Ca ce n'est pas une surcharge, c'est un héritage multiple. Quand tu écris class toto(xxx) tu crées une classe "toto" qui hérite (récupère) tous les attributs et méthodes de "xxx". Quand tu écris class toto(xxx, yyy) c'est la même chose sauf que ta classe "toto" hérite tous les attributs et méthodes de "xxx" et "yyy".
    Donc en écrivant class QWindow(QMainWindow, RechercheCommune) je crée un objet qui hérite à la fois d'un QMainWindow et à la fois d'un RechercheCommune. Il possède donc en natif la méthode "rechercheCommune()" qu'il peut appeler donc directement. Ca reste conforme à ton souci de "cleaneage".
    Juste que Qt est un peu complexe et donc l'héritage multiple n'est pas permis entre 2 objets Qt (tu peux pas hériter à la fois d'un QLabel et d'un QPushButton). Mais il est permis entre un objet PyQt et un objet autre (ici RechercheCommune).
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. Réponses: 2
    Dernier message: 30/07/2016, 18h38
  2. Réponses: 1
    Dernier message: 23/03/2012, 15h41
  3. Réponses: 8
    Dernier message: 12/01/2011, 19h00
  4. Réponses: 5
    Dernier message: 18/12/2009, 17h05
  5. Problème pour créer des objets de la même classe
    Par Dietzer dans le forum Code::Blocks
    Réponses: 1
    Dernier message: 25/06/2009, 17h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo