Contenu | Rechercher | Menus

Annonce

L'équipe des administrateurs et modérateurs du forum vous invite à prendre connaissance des nouvelles règles.
En cas de besoin, vous pouvez intervenir dans cette discussion.

N'oubliez pas de cocher la case « Ajustement pour l'heure d'été » dans votre profil.

Ubuntu 16.04 LTS
Commandez vos DVD et clés USB Ubuntu-fr !

Pour en savoir un peu plus sur l'équipe du forum.

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

#1 Le 11/04/2018, à 11:44

Hourra!

[Résolu] Gestion du retour d'une fenêtre secondaire Pyhton 3.5

Bonjour à tous,

Voici mon souci :

J'écris un programme sous Python 3.5, et je dois lancer la fenêtre de configuration de ce programme.
Lorsque la fenêtre principale s'ouvre, j'ai un bouton qui lance un second script, dans un fichier .py séparé.
Comme d'habitude, je fais donc "import Config", puis, à un moment donné, dans le programme, j'appelle "ConfigSys" qui est dans un "def" d'un fichier secondaire.

Tout fonctionne bien, ma page de config se lance, mais directement, j'obtiens bien entendu un "return None" venant de mon sous-programme, et le programme principal continue sa lancée.

Comment pourrais-je procéder pour que le fichier "ConfigSys" ne renvoie un "return" que quand moi je l'ai décidé ?

J'ai retourné le net, je ne vois rien à ce sujet.


Merci à vous,

Geoffroy

Dans le fichier principal :

def Config():

    """
    Lance la configuration du système
    """
    Interface.GestionsBouton(6)
    P = ConfigSys (logger)
    
    print ('P = ',P) # Return "None" directement

Dans le fichier Config.py :

from tkinter import *
from tkinter.messagebox import *
from tkinter import Tk, PhotoImage, Canvas
import smtplib


def ConfigSys(logger):

    if __name__ != '__main__':

        """
        Initialisation de la fenêtre principale
        & des différents cannevas.
        """
        
        
        global P, Canvas_Configuration, L, returning, Entrees

        L = logger
        Fenetre=Toplevel()
        Fenetre.title('GMTLog Config')
        Fenetre.geometry("850x600")
        Fenetre.update()
        returning = 0
        
        P = PanedWindow(Fenetre, orient=VERTICAL)
        
        Canvas_Titre = LabelFrame(P, height = 20)
        Canvas_Configuration = LabelFrame(P, text="Configuration. (Obligatoire)", font = 'Arial 12 bold', fg='Navy', height=30)
        Canvas_Adresse = LabelFrame(P, text="Adresse. (Obligatoire)", font = 'Arial 12 bold', fg='Navy')
        Canvas_Equipement = LabelFrame(P, text="Equipement. (Facultative)", font = 'Arial 12 bold', fg='Navy')
        Canvas_Validation = LabelFrame(P, text="Validation des données.", font = 'Arial 12 bold', fg='Navy')
        Fenetre.protocol("WM_DELETE_WINDOW", Fenetre.iconify)

        P.add(Canvas_Titre)
        Intro = Label(Canvas_Titre, height=3, width=60, text='Configuration du log.', font = 'Arial 12 bold', fg='Navy', justify=CENTER)
        Intro.pack()

        P.add(Canvas_Configuration)
     
        P.pack()

        Fenetre.protocol("WM_DELETE_WINDOW", Fenetre.iconify)

        """
        Ajout des différents champs dans le canevas 'Canvas_Configuration'
        """

        L.info('Ajout des différents champs dans le canevas "Canvas_Configuration"')

        Txt = ['Call :','Décallage UTC :','Nom :','Prénom :','Power :','Section :','Mail :','Nom du contest :','date :','Points par contact :']
        Pos = [[0,0,8,8, ""],[0,2,15,3,"-2"], [1,0,8,20,""],[1,2,8,20,""],
               [2,0,8,7, "100 W"],[2,2,8,5,"XXX"],[3,0,8,30,"alain@dupont.be"],
               [4,0,15,30,"Contest UBA de printemps"],[4,2,10,15,"01/01/2018"],
               [5,0,20,3,"3"]]

        
        #Pos = [[Text+Label Row, Text+Label Column, Largeur Text, Largeur Label, textvariable]]
        Var = {}
        Entrees = {}

        for i in range(10):
            Entrees[i] = {
                'position':i
                }
            TF = 1
            State = 'normal'
            if i == 0:
                TF = 1
                State = 'normal'
                
            
            TextItem = Label(Canvas_Configuration, justify = RIGHT, anchor=E, width = Pos[i][2], text = Txt[i], font='arial 12 bold', fg='red', pady=10)
            TextItem.grid(row = Pos[i][0], column = Pos[i][1])
            
            LabelVar = StringVar(value = Pos[i][4])
            LabelItem = Entry(Canvas_Configuration, textvariable = LabelVar, width = Pos[i][3], takefocus = TF, justify=LEFT)
            LabelItem.grid(row = Pos[i][0], column = Pos[i][1]+1)
            LabelItem['state'] = State
            #LabelItem.bind('<FocusOut>', ignore)
            LabelItem.event_add('<<KEY>>','<Tab>')
            LabelItem.bind('<<KEY>>', lambda event, clef=i:TabEntry(event, clef))

            Var[i] = {
                'variable' : LabelVar,
                'label' : TextItem,
                'entry' : LabelItem,
                'state' : LabelItem['state'],
                }
            Entrees[i].update(Var[i])

        Entrees[0]['entry'].focus_set()
        TxtBouton = ['Validate','Cancel','green','red']
        
        Boutons = {}
        Var = {}

        for i in range(2):
            Boutons[i] = {
                'position':i
                }

            State = 'normal'
            if i == 1:
                State = 'disable'

            LabelBouton = StringVar(value=TxtBouton[i])
            newbutton = Button(Canvas_Configuration, textvariable = LabelBouton, width = 20, takefocus = 1)
            newbutton.grid(row = 6, column=i+1)
            newbutton['state'] = State
            newbutton.bind('<Button-1>', lambda event, clef=i:Commande_Bouton(event, clef))
            Var[i] = {
                'label' : LabelBouton,
                'state' : State,
                'variable' : newbutton
                }
            Boutons[i].update(Var[i])
    
def ignore():
    pass

def TabEntry(event, clef):
    print (clef)
    if clef == 2 or clef == 3:
        var = Entrees[clef]['variable'].get()

        Entrees[clef]['variable'].set(var[0].upper()+var[1:])
        pass
    Entrees[clef]['variable'].set(Entrees[clef]['entry'].get().upper())
        

def Commande_Bouton(event, i):
    # A définir
    pass

Linux 16.04.4, Python 3.5.2

Dernière modification par Hourra! (Le 12/04/2018, à 10:33)

Hors ligne

#2 Le 11/04/2018, à 14:24

bipede

Re : [Résolu] Gestion du retour d'une fenêtre secondaire Pyhton 3.5

Même si je n'ai pas tout compris à ce que tu veux obtenir, je suppose que tu voudrais que ConfigSys () affiche une boîte de dialogue qui te permet de valider des paramètres que tu voudrais récupérer.
Le code ci-dessous utilise les capacités objet de python en créant une classe ConfigSys dérivée de tk.TopLevel qui comprend une propriété de classe paramsARecuperer dans laquelle on va placer les paramètres à récupérer lors de l'appui sur le bouton valider pour pouvoir les retrouver une fois la fenêtre de paramétrage détruite.
Dans la fonction Config() on instancie la fenêtre à partir de la classe ConfigSys, on la rend modale à l'aide de la méthode grab_set(), on attend ensuite sa fermeture avec la méthode wait_window(fenêtreQuiDoitEtreFermee) et enfin on récupère les paramètres...

from tkinter import *
from tkinter.messagebox import *
from tkinter import Tk, PhotoImage, Canvas
import smtplib


class ConfigSys(Toplevel):
    
    paramsARecuperer = []
    
    def __init__(self, master, logger=None):
        Toplevel.__init__(self, master)
    
        #L = logger
        self.title('GMTLog Config')
        self.geometry("850x600")
        self.update()
        returning = 0
    
        P = PanedWindow(self, orient=VERTICAL)
    
        Canvas_Titre = LabelFrame(P, height = 20)
        Canvas_Configuration = LabelFrame(P, text="Configuration. (Obligatoire)", font = 'Arial 12 bold', fg='Navy', height=30)
        Canvas_Adresse = LabelFrame(P, text="Adresse. (Obligatoire)", font = 'Arial 12 bold', fg='Navy')
        Canvas_Equipement = LabelFrame(P, text="Equipement. (Facultative)", font = 'Arial 12 bold', fg='Navy')
        Canvas_Validation = LabelFrame(P, text="Validation des données.", font = 'Arial 12 bold', fg='Navy')

        P.add(Canvas_Titre)
        self.Intro = Label(Canvas_Titre, height=3, width=60, text='Configuration du log.', font = 'Arial 12 bold', fg='Navy', justify=CENTER)
        self.Intro.pack()

        P.add(Canvas_Configuration)
 
        P.pack()

        self.protocol("WM_DELETE_WINDOW", self.iconify)

        """
        Ajout des différents champs dans le canevas 'Canvas_Configuration'
        """

        #L.info('Ajout des différents champs dans le canevas "Canvas_Configuration"')

        Txt = ['Call :','Décallage UTC :','Nom :','Prénom :','Power :','Section :','Mail :','Nom du contest :','date :','Points par contact :']
        Pos = [[0,0,8,8, ""],[0,2,15,3,"-2"], [1,0,8,20,""],[1,2,8,20,""],
            [2,0,8,7, "100 W"],[2,2,8,5,"XXX"],[3,0,8,30,"alain@dupont.be"],
            [4,0,15,30,"Contest UBA de printemps"],[4,2,10,15,"01/01/2018"],
            [5,0,20,3,"3"]]

    
        #Pos = [[Text+Label Row, Text+Label Column, Largeur Text, Largeur Label, textvariable]]
        Var = {}
        Entrees = {}

        for i in range(10):
            Entrees[i] = {
                'position':i
                }
            TF = 1
            State = 'normal'
            if i == 0:
                TF = 1
                State = 'normal'
            
        
            TextItem = Label(Canvas_Configuration, justify = RIGHT, anchor=E, width = Pos[i][2], text = Txt[i], font='arial 12 bold', fg='red', pady=10)
            TextItem.grid(row = Pos[i][0], column = Pos[i][1])
        
            LabelVar = StringVar(value = Pos[i][4])
            LabelItem = Entry(Canvas_Configuration, textvariable = LabelVar, width = Pos[i][3], takefocus = TF, justify=LEFT)
            LabelItem.grid(row = Pos[i][0], column = Pos[i][1]+1)
            LabelItem['state'] = State
            #LabelItem.bind('<FocusOut>', ignore)
            LabelItem.event_add('<<KEY>>','<Tab>')
            LabelItem.bind('<<KEY>>', lambda event, clef=i:self.TabEntry(event, clef))

            Var[i] = {
                'variable' : LabelVar,
                'label' : TextItem,
                'entry' : LabelItem,
                'state' : LabelItem['state'],
            }
            Entrees[i].update(Var[i])

        Entrees[0]['entry'].focus_set()
        TxtBouton = ['Validate','Cancel','green','red']
    
        Boutons = {}
        Var = {}

        for i in range(2):
            Boutons[i] = {
                'position':i
            }

            State = 'normal'
            if i == 1:
                State = 'disable'

            LabelBouton = StringVar(value=TxtBouton[i])
            newbutton = Button(Canvas_Configuration, textvariable = LabelBouton, width = 20, takefocus = 1)
            newbutton.grid(row = 6, column=i+1)
            newbutton['state'] = State
            newbutton.bind('<Button-1>', lambda event, clef=i:self.Commande_Bouton(event, clef))
            Var[i] = {
                'label' : LabelBouton,
                'state' : State,
                'variable' : newbutton
            }
            Boutons[i].update(Var[i])
    
    def ignore(self):
        pass

    def TabEntry(self, event, clef):
        print (clef)
        if clef == 2 or clef == 3:
            var = Entrees[clef]['variable'].get()

            Entrees[clef]['variable'].set(var[0].upper()+var[1:])
            pass
        Entrees[clef]['variable'].set(Entrees[clef]['entry'].get().upper())
        

    def Commande_Bouton(self, event, i):
        # A définir
        ConfigSys.paramsARecuperer = ["param1", "param2", "param3"]
        self.destroy()


def Config():

    """
    Lance la configuration du système
    """
    #Interface.GestionsBouton(6)
    P = ConfigSys (window)
    P.grab_set()
    window.wait_window(P)
    
    
    print (ConfigSys.paramsARecuperer)

window = Tk()

Button(window, text="Click Me", command=Config).pack()

window.mainloop()

Desktop: MSI - Intel® Core™ i5-3330 CPU @ 3.00GHz × 4 - RAM 8 go- Ubuntu 18.04 - Système sur SSD 64 Go - /home sur HDD 500 Go.
Laptop: DELL Inspiron-15 3567 - Intel® Core™ i5-7200 CPU @ 2.50GHz × 4 - RAM 8 go - HDD 1 To - Ubuntu 18.04 avec /home séparé.

Mon site: Les contributions du bipède

Hors ligne

#3 Le 11/04/2018, à 16:26

Hourra!

Re : [Résolu] Gestion du retour d'une fenêtre secondaire Pyhton 3.5

Salut Bipede,

Oui, c'est tout à fait cela.
Maintenant, j'essaie de l'adapter à mon programme, car le Config est appelé depuis le programme principal.

Donc, je n'ai pas ton "window" dans mon programme !

Merci.

Hors ligne

#4 Le 11/04/2018, à 19:26

bipede

Re : [Résolu] Gestion du retour d'une fenêtre secondaire Pyhton 3.5

Si j'ai un conseil à te donner, plutôt que d'utiliser des fonctions pour construire tes ihm, utilise des objets qui dérivent des classes tkinter.
Python tire sa puissance de la poo.


Desktop: MSI - Intel® Core™ i5-3330 CPU @ 3.00GHz × 4 - RAM 8 go- Ubuntu 18.04 - Système sur SSD 64 Go - /home sur HDD 500 Go.
Laptop: DELL Inspiron-15 3567 - Intel® Core™ i5-7200 CPU @ 2.50GHz × 4 - RAM 8 go - HDD 1 To - Ubuntu 18.04 avec /home séparé.

Mon site: Les contributions du bipède

Hors ligne