Programmer une fenêtre indépendante du reste du programme et interactive -python [Résolu]

Signaler
Messages postés
367
Date d'inscription
vendredi 1 septembre 2017
Statut
Membre
Dernière intervention
17 novembre 2020
-
Messages postés
662
Date d'inscription
lundi 23 mars 2020
Statut
Membre
Dernière intervention
29 novembre 2020
-
Bonjour,

Je cherche à programmer une interface graphique simple en python qui doit afficher un message, une icône et deux bouton (dont le texte peux changer selon le message qui sera affiché).
Dans sa globalité, mon programme sert à afficher des messages provenant du réseaux sous forme graphique (il n'y a pas de soucie pour récupérer les messages du réseaux). Mais le message affiché dans la fenêtre pourra être modifié si un nouveau message du réseaux arrive.

La question est donc :
Quel est la meilleure manière de structuré le code de la fenêtre de sorte qu'elle puisse être indépendante du reste du programme (afin que la fonction bloquante "exec_" de qt n'empêche pas le reste du programme d'écouter le réseaux quand la fenêtre est ouverte), et de sorte que l'on puisse modifier le message contenue dans la fenêtre depuis l'extérieur de la fenêtre. Et que l'on puisse ouvrir/fermer la fenêtre autant de fois que l'on veut (avec tkinter je me suis retrouvé avec des threads qui ne se terminais jamais, les miens se retrouvais bloqué. Toute la partie graphique se retrouvais bloqué, le reste du programme fonctionnais et écoutais bien le réseaux...).
Je me tourne vers qt. Mais j'ai encore des problèmes (des threads qui ont l'air de vouloir se terminer avant d'autres quand je tente de fermer la fenêtre)... je ne connais pas très bien les bibliothèques qt.

Bref, un beau bordel... J'ai tenté plein de solution avec des Threads :
- fenêtre définis dans le __init__ de la classe
- fenêtre définis dans le thread

Voilà ce que j'ai pour le moment, c'est du gros bricolage, je cherchais à voir comment la fenêtre se comportait :
#!/usr/bin/python
# -*- coding : utf-8 -*-

import os
import sys
from time import sleep
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from threading import Thread

class HelloApplication(QApplication, Thread) :
    def __init__ (self, args) :
        Thread.__init__(self)
        QApplication.__init__ (self,args)
        self.window_exist = True
        self.input_file = "/tmp/alert/window_input"
        self.output_file = "/tmp/alert/window_output"

        # Creation et affichage d'un objet HelloButton
        self.button=QPushButton("texte !")
        self.button.clicked.connect(self.quit)
        self.button.show()
        # Traitement des divers evenements
        self.connect(self,SIGNAL("lastWindowClosed()"), self.quit)

    def run(self) :
        print("ok")
        while self.window_exist :
            if os.path.exists(self.input_file) :
                msg = open(self.input_file, 'r').read()[:-1]
                if msg == "stop" :
                    self.window_exist = False
                    print("I quit !")
            sleep(1.4)
        print(3)
    def quit(self) :
        os.system("echo \"stop\" > /tmp/alert/window_input")
        sleep(0.2)

def main() :
    app=HelloApplication(sys.argv)
    app.start()
    print(2)
    app.exec_()
    print(4)
    app.join()
    print(5)

def startstop(oui=False) :
    if oui :
        os.system("echo \"stop\" > /tmp/alert/window_input")
    else :
        os.system("echo \"\" > /tmp/alert/window_input")

if __name__ == "__main__" :
    startstop()

    t = Thread(target=main)
    t.start()
    print(1)
    t.join()
    print(6)



config : python3.7 → J'ai aussi besoin que ce soit multiplateforme (linux, windows)...

2 réponses

Messages postés
367
Date d'inscription
vendredi 1 septembre 2017
Statut
Membre
Dernière intervention
17 novembre 2020
112
Finalement à force de recherche j'ai trouvé une solution pour tkinter (j'ai crus voir qu'il y en avait aussi pour qt et gtk). Plutôt que d'utiliser la boucle mainloop() j'utilise l'évènement update().
Donc en le mettant dans ma boucle qui écoute les évènements extérieurs je peux afficher ma fenêtre et interagir avec celle-ci sans que cette boucle se bloque en attente de fermeture de la fenêtre.
Ça donne quelque chose comme ça :

from tkinter import *
from time import sleep

class Application(Tk) :
    def __init__(self) :
        Tk.__init__(self)
        self.exists = True
        self.texte = Label(self, text="rien pour le moment")
        self.afficher = Button(self, text="message", command=self.message)
        self.bouton = Button(self, text="fermer", command=self.exit)
        self.texte.pack()
        self.afficher.pack()
        self.bouton.pack()

    def exit(self) :
        self.exists = "fermee"
        self.destroy()

    def message(self) :
        message = """maintenant il y a un message, et tu ne peux plus appuyer sur 
[fermer] parce que on ne fait plus App.update() dans la fonction main()"""
        self.texte.config(text=message)
        self.texte.update()
        self.exists = False #ça ne sert à rien ici, mais utile quand la fenêtre est détruite,
                            #l'objet existe toujours et tenter de faire un update() créer une erreur...

def main() :
    App = Application()
    while App.exists != "fermee" :
        print("Des choses à faire...")
        #C'est ici qu'on affiche la fenêtre et écoute les évènements des widgets (si la fenêtre existe)
        if App.exists : App.update()
        print(App.exists)
        print("D'autre choses à faire...")
        sleep(0.5) # ralenti la réactivité des widgets...
    print("fin...")

if __name__ == "__main__" :
    main()
Messages postés
662
Date d'inscription
lundi 23 mars 2020
Statut
Membre
Dernière intervention
29 novembre 2020
80
Bonjour,

Super, tu peux marquer ton appel comme "résolu"