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

Tkinter Python Discussion :

création d'une fenêtre modale


Sujet :

Tkinter Python

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut création d'une fenêtre modale
    Bonjour, je cherche à créer une fenêtre modale qui apparait lorsqu'on clique sur le bouton droit de la souris. Je veux réaliser quelque chose du genre :

    Nom : modal.png
Affichages : 2477
Taille : 34,1 Ko

    Pour l'instant, mon code 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
     
    from tkinter import *
    from PIL import Image, ImageTk
    from tkinter import filedialog, ttk
    from tkinter.filedialog import askopenfile
    import os
    from os.path import basename
     
    class AutoScrollbar(Scrollbar):
        # a scrollbar that hides itself if it's not needed.  only
        # works if you use the grid geometry manager.
        def set(self, lo, hi):
            if float(lo) <= 0.0 and float(hi) >= 1.0:
                self.grid_remove()
            else:
                self.grid()
            Scrollbar.set(self, lo, hi)
        def pack(self, **kw):
            raise TclError ("cannot use pack with this widget")
        def place(self, **kw):
            raise TclError ("cannot use place with this widget")
     
    def openFile():
        global filename
        file = askopenfile(parent=root,title='Select a File')
        filename = file.name
        t = file.read()
     
        #print(nb.index('current'))
     
        basename(filename)
     
        frame1 = create_frame(nb, t)
        nb.add(frame1, text=basename(filename))
        tbox1 = Text(frame1, wrap=WORD)    
        #print(tbox1)
        print(nb.index(frame1))
        #print(nb.select(nb.index("current")))
     
        nb.select(nb.index(frame1))
     
        file.close()
     
    def callback():
        frame.focus_set()
        print ("clicked at", event.x, event.y)
     
    def create_frame(master, t):
        frame = Frame(master, bd=2, relief=SUNKEN)
        yscrollbar = AutoScrollbar(frame)
        yscrollbar.grid(row=0, column=1, sticky=N+S)
        text = Text(frame, 
                    yscrollcommand=yscrollbar.set, background="beige")
     
        #print ("Mon Onglet : "+str(text))
     
        text.grid(row=0, column=0, sticky='nwse') # expansion du widget Text
     
        frame.grid_columnconfigure(0, weight=1) # expansion de la colonne
        frame.grid_rowconfigure(0, weight=1) # expansion de la colonne
     
        text.insert(0.0, t)
     
        #print(text.grid)
     
        return frame
     
     
    if __name__ == '__main__':
        root = Tk()
     
        root.title("MonkeyCode Editor")
     
        menubar = Menu(root)
        filemenu = Menu(menubar)
        EditMenu = Menu(menubar)
     
        filemenu.add_command(label="Ouvrir", command=openFile)
        menubar.add_cascade(label="Fichier", menu=filemenu)
     
     
        EditMenu.add_command(label="Couper", \
                         accelerator="Ctrl+X", \
                         command=lambda: \
                                 root.focus_get().event_generate('<<Cut>>'))
     
        EditMenu.add_command(label="Copier", \
                         accelerator="Ctrl+C", \
                         command=lambda: \
                                 root.focus_get().event_generate('<<Copy>>'))
     
        EditMenu.add_command(label="Coller", \
                             accelerator="Ctrl+V", \
                             command=lambda: \
                                     root.focus_get().event_generate('<<Paste>>'))
     
        menubar.add_cascade(label="Édition",menu=EditMenu)
     
        root.config(menu=menubar)   
     
        nb = ttk.Notebook(root)    
     
        root.update()
     
        def fonc3(event):
     
     
            cadre = Frame(root, width =200, height =150, bg="yellow")
            #cadre.pack()
            #chaine = Label(cadre, text = "VIDE")
            #chaine.pack()
     
     
            #cadre = Frame(root, bg='green', width=300, height=200)
            cadre.pack(fill=X, expand=Y)
            #cadre.grid_propagate(0)
            cadre.rowconfigure(0, weight=1)
            cadre.columnconfigure(0, weight=1)
            Label(cadre, text='Couper').grid(row=1, column=0, sticky='nesw')
            Label(cadre, text='Copier').grid(row=2, column=1, sticky='ne')
            Label(cadre, text='Coller').grid(row=3, column=1)
     
            modale = TopLevel()
            fermer = Button(modale, text="Fermer", command=modale.destroy)
            fermer.pack()
     
     
        def fonc2(event):
            print("Molette")
     
     
        def fonc1(event):
            print("Bouton gauche")
     
        cadre = Frame(root, width =200, height =150, bg="yellow")
     
        root.bind("<Button-1>", fonc1)
        root.bind("<Button-2>", fonc2)
        root.bind("<Button-3>", fonc3)
     
        #frame1 = create_frame(nb)
        #nb.add(frame1, text="Text1")
        #tbox1 = Text(frame1, wrap=WORD)    
        #print(tbox1)
     
        t=""
     
        frame2 = create_frame(nb, t)
        nb.add(frame2, text="new 1")
        tbox2 = Text(frame2, wrap=WORD)
        print(tbox2)  
     
        nb.pack(expand=YES, fill=BOTH)
     
        mainloop()
    Lorsqu'on clique sur le bouton droit, la fenêtre qui apparaît n''est pas modale. C'est ce problème que je veux résoudre en priorité.
    Auriez-vous une solution à me proposer, svp?
    Je vous en remercie d'avance.
    Arsène

  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 778
    Points
    36 778
    Par défaut
    Salut,

    Citation Envoyé par Arsene12 Voir le message
    Lorsqu'on clique sur le bouton droit, la fenêtre qui apparaît n''est pas modale. C'est ce problème que je veux résoudre en priorité.
    Auriez-vous une solution à me proposer, svp?
    Et si vous commenciez par chercher un peu sur Internet? Vous auriez trouvé le petit tuto. d'effbot sur le sujet qui, comme pour la Scrollbar, est un bon point de départ.

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

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut
    Merci pour ce lien. En réfléchissant je me suis dis que c'est peut-être pas une fenêtre modale qu'il me faut car je veux pas qu'elle ait de bordure ni une croix en haut à droite.
    J'ai vu un autre lien : coursPython. Ça doit être un peu compliqué à réaliser. Je vais devoir installer un binding, je crois que c'est comme ça que ça s'appelle : PyQt5 ou PyQt4. J'ai téléchargé le fichier PyQt5-5.10.1-5.10.1-cp35.cp36.cp37.cp38-none-win_amd64 mais je sais pas encore comment l'installer.
    Je viens aussi de voir un sujet intéressante dans le forum d'ici : fenêtre sans bord
    Je vais l'étudier car je crois que ce que je veux faire, c'est peut-être ça, avec une fenêtre Toplevel.

  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 778
    Points
    36 778
    Par défaut
    Citation Envoyé par Arsene12 Voir le message
    Je vais l'étudier car je crois que ce que je veux faire, c'est peut-être ça, avec une fenêtre Toplevel.
    Ah ben si vous ne savez pas trop exprimer ce que vous voulez (une interface graphique c'est tout un vocabulaire!) pas facile de savoir quoi coder avec tkinter et c'est pas changer de GUI qui vous aidera.

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

  5. #5
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut
    J'ai installé PyQt5-5 et utilisé top.overrideredirect(1). Tout a bien marché. J'ai maintenant une fenêtre sans bord qui ressemble à celle que je voulais faire. Elle contient des labels et il me reste à régler un dernier point :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    L1=Label(top, text='Couper', activebackground="blue").grid(row=1, column=0, padx=20, sticky='w')
    Lorsque je survole mon label, la couleur de fond reste la même (activebackground="blue" ne marche pas).

    ça ne marche pas non plus si je met un bouton à la place du label. Auriez-vous une idée pour régler ce problème svp?

    Je vous donne le code :

    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
     
    from tkinter import *
    from PIL import Image, ImageTk
    from tkinter import filedialog, ttk
    from tkinter.filedialog import askopenfile
    import os
    from os.path import basename
     
    varGlobal = 0
     
    class AutoScrollbar(Scrollbar):
        # a scrollbar that hides itself if it's not needed.  only
        # works if you use the grid geometry manager.
        def set(self, lo, hi):
            if float(lo) <= 0.0 and float(hi) >= 1.0:
                self.grid_remove()
            else:
                self.grid()
            Scrollbar.set(self, lo, hi)
        def pack(self, **kw):
            raise TclError ("cannot use pack with this widget")
        def place(self, **kw):
            raise TclError ("cannot use place with this widget")
     
    def openFile():
        global filename
        file = askopenfile(parent=root,title='Select a File')
        filename = file.name
        t = file.read()
     
        #print(nb.index('current'))
     
        basename(filename)
     
        frame1 = create_frame(nb, t)
        nb.add(frame1, text=basename(filename))
        tbox1 = Text(frame1, wrap=WORD)    
        #print(tbox1)
        #print(nb.index(frame1))
        #print(nb.select(nb.index("current")))
     
        nb.select(nb.index(frame1))
     
        file.close()
     
    def callback():
        frame.focus_set()
        print ("clicked at", event.x, event.y)
     
    def create_frame(master, t):
        frame = Frame(master, bd=2, relief=SUNKEN)
        yscrollbar = AutoScrollbar(frame)
        yscrollbar.grid(row=0, column=1, sticky=N+S)
        text = Text(frame, 
                    yscrollcommand=yscrollbar.set, background="beige")
     
        #print ("Mon Onglet : "+str(text))
     
        text.grid(row=0, column=0, sticky='nwse') # expansion du widget Text
     
        frame.grid_columnconfigure(0, weight=1) # expansion de la colonne
        frame.grid_rowconfigure(0, weight=1) # expansion de la colonne
     
        text.insert(0.0, t)
        #print(text.grid) 
        return frame
     
    if __name__ == '__main__':
        root = Tk()
     
        root.title("MonkeyCode Editor")    
     
        menubar = Menu(root)
        filemenu = Menu(menubar)
        EditMenu = Menu(menubar)
     
        filemenu.add_command(label="Ouvrir", command=openFile)
        menubar.add_cascade(label="Fichier", menu=filemenu)    
     
        EditMenu.add_command(label="Couper", \
                         accelerator="Ctrl+X", \
                         command=lambda: \
                                 root.focus_get().event_generate('<<Cut>>'))
     
        EditMenu.add_command(label="Copier", \
                         accelerator="Ctrl+C", \
                         command=lambda: \
                                 root.focus_get().event_generate('<<Copy>>'))
     
        EditMenu.add_command(label="Coller", \
                             accelerator="Ctrl+V", \
                             command=lambda: \
                                     root.focus_get().event_generate('<<Paste>>'))
     
        menubar.add_cascade(label="Édition",menu=EditMenu)
        root.config(menu=menubar)    
        nb = ttk.Notebook(root)    
     
        root.update()
     
        def ferme():
            global varGlobal
            for widget in root.winfo_children():
                if isinstance(widget,Toplevel):
                    widget.destroy()
                    varGlobal = 0
     
        def fonc4(event):
            print ("TOP FENETRE")                
     
        def fonc3(event):
            global varGlobal
            if varGlobal == 0 :
                print ("EXISTE PAS")            
                varGlobal = 1        
                top = Toplevel(root)
                separator = ttk.Separator(top, orient="horizontal")
                top.overrideredirect(1)
                #print(top.geometry(), root.geometry()) # Affiche 1x1+0+0 1x1+0+0
                top.geometry("{}x{}+{}+{}".format(200, 120, 400, 400))
     
                L1=Label(top, text='Couper', activebackground="blue").grid(row=1, column=0, padx=20, sticky='w')
                L2=Label(top, text='Copier', activebackground="blue").grid(row=2, column=0, padx=20, sticky='w')
                L3=Label(top, text='Coller', activebackground="blue").grid(row=3, column=0, padx=20, sticky='w')
                separator.grid(row=4, column=0, sticky="nwse")
                L4=Label(top, text='Rechercher', activebackground="blue").grid(row=5, column=0, padx=20, sticky='w')            
                B1=Button(top, text='Quitter', activebackground="blue", command=ferme).grid(row=6, column=0, padx=20, sticky='w')
     
                top.configure(bd=1, relief=RAISED)
                top.rowconfigure(7, weight=0)
                top.columnconfigure(0, weight=0)
                top.bind("<Button-1>", fonc4)
     
            else :
                print ("EXISTE")            
                ferme() 
     
        #print(top.geometry()) # Affiche 1x1+400+400
     
        def fonc1(event):
            ferme()                  
     
        root.bind("<Button-3>", fonc3)
        root.bind("<Button-1>", fonc1)
     
        t=""
     
        frame2 = create_frame(nb, t)
        nb.add(frame2, text="new 1")
        tbox2 = Text(frame2, wrap=WORD)
        #print(tbox2)  
     
        nb.pack(expand=YES, fill=BOTH)
     
        mainloop()

  6. #6
    Membre confirmé

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Points : 503
    Points
    503
    Billets dans le blog
    1
    Par défaut


    Sur les labels il n'y a aucun événement par défaut reliés à ces actions de survol par la souris et de focus.

    C'est à toi de les définir, un exemple.

    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
    import tkinter as tk
     
    root = tk.Tk()
    root.geometry('200x200')
     
    lbl = tk.Label(
        root,
        text="coucou",
        background="black",
        foreground="white",
        activebackground="yellow",
        activeforeground="red",
        takefocus=1,
        state=tk.NORMAL,
        highlightthickness=2,
        highlightbackground="orange",
        highlightcolor="green",
    )
    lbl.grid()
     
    bt = tk.Button(root, text='bout 2')
    bt.grid()
     
    lbl.bind('<FocusIn>', lambda e: lbl.config(state='active'))
    lbl.bind('<Enter>', lambda e: lbl.config(state='active'))
    lbl.bind('<FocusOut>', lambda e: lbl.config(state='normal'))
    lbl.bind('<Leave>', lambda e: lbl.config(state='normal'))
     
    root.bind('<KeyPress-Tab>', lambda e: print(root.focus_lastfor()))
     
    root.mainloop()
    Évidemment comme tu as plusieurs labels nécessitant d'avoir cette fonctionnalité, il va falloir créer une classe héritant de Label pour gérer ça.

    Mais ça ne serait pas mieux de faire ce que tu souhaites avec un widget menu ? Pour moi ce serait quand même plus approprié de se servir de ce widget.
    Le temps ronge l'amour comme l'acide.

  7. #7
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut
    Merci beaucoup pour cette aide précieuse. Je suis maintenant parvenu grâce à vous à faire changer la couleur de fond du label lorsqu'on le survole.
    Pour pouvoir ajouter relier mes labels à une fonction, j'avais pensé utiliser les coordonnées du click dans la fenêtre modale. Malheureusement je n'arrive à récupérer les coordonnées du click qu'à l'intérieur du label. Vous pouvez vérifier en exécutant le code (les coordonnées X et Y s'affichent en bas de la fenêtre principale). Mon code fonctionne avec python 3.6 auquel il faut ajouter PyQt5-5.
    Pour faire apparaître la fenêtre modale, il faut faire un click droit. Pour la faire disparaître, un autre click droit. Et ainsi de suite...

    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
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    from tkinter import *
    from PIL import Image, ImageTk
    from tkinter import filedialog, ttk
    from tkinter.filedialog import askopenfile
    import os
    from os.path import basename
     
    varGlobal = 0
     
    class AutoScrollbar(Scrollbar):
        # a scrollbar that hides itself if it's not needed.  only
        # works if you use the grid geometry manager.
        def set(self, lo, hi):
            if float(lo) <= 0.0 and float(hi) >= 1.0:
                self.grid_remove()
            else:
                self.grid()
            Scrollbar.set(self, lo, hi)
        def pack(self, **kw):
            raise TclError ("cannot use pack with this widget")
        def place(self, **kw):
            raise TclError ("cannot use place with this widget")
     
    def openFile():
        global filename
        file = askopenfile(parent=root,title='Select a File')
        filename = file.name
        t = file.read()
     
        #print(nb.index('current'))
     
        basename(filename)
     
        frame1 = create_frame(nb, t)
        nb.add(frame1, text=basename(filename))
        tbox1 = Text(frame1, wrap=WORD)    
        #print(tbox1)
        #print(nb.index(frame1))
        #print(nb.select(nb.index("current")))
     
        nb.select(nb.index(frame1))
     
        file.close()
     
    def callback():
        frame.focus_set()
        print ("clicked at", event.x, event.y)
     
    def create_frame(master, t):
        frame = Frame(master, bd=2, relief=SUNKEN)
        yscrollbar = AutoScrollbar(frame)
        yscrollbar.grid(row=0, column=1, sticky=N+S)
        text = Text(frame, 
                    yscrollcommand=yscrollbar.set, background="beige")
     
        #print ("Mon Onglet : "+str(text))
     
        text.grid(row=0, column=0, sticky='nwse') # expansion du widget Text
     
        frame.grid_columnconfigure(0, weight=1) # expansion de la colonne
        frame.grid_rowconfigure(0, weight=1) # expansion de la colonne
     
        text.insert(0.0, t)
        #print(text.grid) 
        return frame
     
    if __name__ == '__main__':
        root = Tk()
     
        root.title("MonkeyCode Editor")    
     
        menubar = Menu(root)
        filemenu = Menu(menubar)
        EditMenu = Menu(menubar)
     
        filemenu.add_command(label="Ouvrir", command=openFile)
        menubar.add_cascade(label="Fichier", menu=filemenu)    
     
        EditMenu.add_command(label="Couper", \
                         accelerator="Ctrl+X", \
                         command=lambda: \
                                 root.focus_get().event_generate('<<Cut>>'))
     
        EditMenu.add_command(label="Copier", \
                         accelerator="Ctrl+C", \
                         command=lambda: \
                                 root.focus_get().event_generate('<<Copy>>'))
     
        EditMenu.add_command(label="Coller", \
                             accelerator="Ctrl+V", \
                             command=lambda: \
                                     root.focus_get().event_generate('<<Paste>>'))
     
        menubar.add_cascade(label="Édition",menu=EditMenu)
        root.config(menu=menubar)    
        nb = ttk.Notebook(root)    
     
        root.update()
     
        def ferme():
            global varGlobal
            for widget in root.winfo_children():
                if isinstance(widget,Toplevel):
                    widget.destroy()
                    varGlobal = 0
     
        def fonc4(event):
            print ("TOP FENETRE")
            print ("Click GAUCHE")
     
        def pointeur(evt):
                    position.configure(text="Clic détecté en X = "+str(evt.x)+", Y = "+str(evt.y))
     
        def fonc3(event):
            global varGlobal
            if varGlobal == 0 :
                print ("EXISTE PAS")            
                varGlobal = 1        
                top = Toplevel(root)
                separator = ttk.Separator(top, orient="horizontal")
                top.overrideredirect(1)
                #print(top.geometry(), root.geometry()) # Affiche 1x1+0+0 1x1+0+0
                top.geometry("{}x{}+{}+{}".format(200, 120, 400, 400))           
     
                L1=Label(top, text='Couper', activebackground="blue")
                L1.grid(row=1, column=0, padx=20, sticky='w')
                L2=Label(top, text='Copier', activebackground="blue")
                L2.grid(row=2, column=0, padx=20, sticky='w')
                L3=Label(top, text='Coller', activebackground="blue")
                L3.grid(row=3, column=0, padx=20, sticky='w')
                separator.grid(row=4, column=0, sticky="nwse")
                L4=Label(top, text='Rechercher', activebackground="blue")
                L4.grid(row=5, column=0, padx=20, sticky='w')            
                B1=Button(top, text='Quitter', activebackground="blue", command=ferme)
                B1.grid(row=6, column=0, padx=20, sticky='w')
     
                top.configure(bd=1, relief=RAISED)
                top.rowconfigure(7, weight=0)
                top.columnconfigure(0, weight=0)
                #top.bind("<Button-1>", fonc4)
     
                L1.bind('<FocusIn>', lambda e: L1.config(state='active'))
                L1.bind('<Enter>', lambda e: L1.config(state='active'))
                L1.bind('<FocusOut>', lambda e: L1.config(state='normal'))
                L1.bind('<Leave>', lambda e: L1.config(state='normal'))
     
                L2.bind('<FocusIn>', lambda e: L2.config(state='active'))
                L2.bind('<Enter>', lambda e: L2.config(state='active'))
                L2.bind('<FocusOut>', lambda e: L2.config(state='normal'))
                L2.bind('<Leave>', lambda e: L2.config(state='normal'))
     
                L3.bind('<FocusIn>', lambda e: L3.config(state='active'))
                L3.bind('<Enter>', lambda e: L3.config(state='active'))
                L3.bind('<FocusOut>', lambda e: L3.config(state='normal'))
                L3.bind('<Leave>', lambda e: L3.config(state='normal'))
     
                L4.bind('<FocusIn>', lambda e: L4.config(state='active'))
                L4.bind('<Enter>', lambda e: L4.config(state='active'))
                L4.bind('<FocusOut>', lambda e: L4.config(state='normal'))
                L4.bind('<Leave>', lambda e: L4.config(state='normal'))
     
                top.bind("<Button-1>", pointeur)
     
            else :
                print ("EXISTE")
                ferme()
     
     
        #print(top.geometry()) # Affiche 1x1+400+400
     
        def fonc1(event):
            ferme()                  
     
        root.bind("<Button-3>", fonc3)
        root.bind("<Button-1>", fonc1)
     
        t=""
     
        frame2 = create_frame(nb, t)
        nb.add(frame2, text="new 1")
        tbox2 = Text(frame2, wrap=WORD)
        #print(tbox2)  
     
        nb.pack(expand=YES, fill=BOTH)
     
        position=Label(root,text="Clic détecté en X =''+'','' Y = ")
        position.pack()
        root.bind("<Button-1>", pointeur)    
     
        mainloop()

  8. #8
    Membre confirmé

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Points : 503
    Points
    503
    Billets dans le blog
    1
    Par défaut
    Et pourquoi ne pas relier chacun de tes labels à un événement "clic" avec sa propre fonction ?
    La doc de tkinter en français http://tkinter.fdex.eu/doc/event.html

    Et sachant que tes labels sont des objets de mêmes types, il faut vraiment te pencher sur la création d'une classe héritant de tkinter.Label pour éviter cette redondance de code.

    Je n'ai pas compris ce que tu signifies par :

    auquel il faut ajouter PyQt5-5
    Tu utilises ces 2 librairies graphiques dans ton application ?
    Le temps ronge l'amour comme l'acide.

  9. #9
    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 778
    Points
    36 778
    Par défaut
    Citation Envoyé par Arsene12 Voir le message
    Pour faire apparaître la fenêtre modale, il faut faire un click droit. Pour la faire disparaître, un autre click droit. Et ainsi de suite...
    Ce que vous essayez de faire s'appelle un pop-up menu. Pour le réaliser avec tkinter vous avez un exemple ici (et c'est encore effbot).

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

  10. #10
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut
    Merci beaucoup pour cette solution. J'aurai du m'orienter dès le départ vers une pop-up plutôt que vers une fenêtre modale.


    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
    180
    181
    182
    from tkinter import *
    from PIL import Image, ImageTk
    from tkinter import filedialog, ttk
    from tkinter.filedialog import askopenfile
    import os
    from os.path import basename
     
    varGlobal = 0
     
    class AutoScrollbar(Scrollbar):
        # a scrollbar that hides itself if it's not needed.  only
        # works if you use the grid geometry manager.
        def set(self, lo, hi):
            if float(lo) <= 0.0 and float(hi) >= 1.0:
                self.grid_remove()
            else:
                self.grid()
            Scrollbar.set(self, lo, hi)
        def pack(self, **kw):
            raise TclError ("cannot use pack with this widget")
        def place(self, **kw):
            raise TclError ("cannot use place with this widget")
     
    def openFile():
        global filename
        file = askopenfile(parent=root,title='Select a File')
        filename = file.name
        t = file.read()
     
        #print(nb.index('current'))
     
        basename(filename)
     
        frame1 = create_frame(nb, t)
        nb.add(frame1, text=basename(filename))
        tbox1 = Text(frame1, wrap=WORD)    
        #print(tbox1)
        #print(nb.index(frame1))
        #print(nb.select(nb.index("current")))
     
        nb.select(nb.index(frame1))
     
        file.close()
     
    def callback():
        frame.focus_set()
        print ("clicked at", event.x, event.y)
     
    def create_frame(master, t):
        frame = Frame(master, bd=2, relief=SUNKEN)
        yscrollbar = AutoScrollbar(frame)
        yscrollbar.grid(row=0, column=1, sticky=N+S)
        text = Text(frame, 
                    yscrollcommand=yscrollbar.set, background="beige")
     
        #print ("Mon Onglet : "+str(text))
     
        text.grid(row=0, column=0, sticky='nwse') # expansion du widget Text
     
        frame.grid_columnconfigure(0, weight=1) # expansion de la colonne
        frame.grid_rowconfigure(0, weight=1) # expansion de la colonne
     
        text.insert(0.0, t)
        #print(text.grid) 
        return frame
     
    if __name__ == '__main__':
        root = Tk()
     
        #w = Label(root, text="Right-click to display menu", width=40, height=20)
        #w.pack()
     
        # create a menu
        popup = Menu(root, tearoff=0)
        popup.add_command(label="Couper", \
                         accelerator="Ctrl+X", \
                         command=lambda: \
                                 root.focus_get().event_generate('<<Cut>>'))
        popup.add_command(label="Copier", \
                         accelerator="Ctrl+C", \
                         command=lambda: \
                                 root.focus_get().event_generate('<<Copy>>'))
     
        popup.add_command(label="Coller", \
                             accelerator="Ctrl+V", \
                             command=lambda: \
                                     root.focus_get().event_generate('<<Paste>>'))
        popup.add_separator()
        popup.add_command(label="Home")
     
     
        def do_popup(event):
            # display the popup menu
            try:
                popup.tk_popup(event.x_root, event.y_root, 0)
            finally:
                # make sure to release the grab (Tk 8.0a1 only)
                popup.grab_release()
     
        root.bind("<Button-3>", do_popup)
     
        root.title("MonkeyCode Editor")    
     
        menubar = Menu(root)
        filemenu = Menu(menubar)
        EditMenu = Menu(menubar)
     
        filemenu.add_command(label="Ouvrir", command=openFile)
        menubar.add_cascade(label="Fichier", menu=filemenu)    
     
        EditMenu.add_command(label="Couper", \
                         accelerator="Ctrl+X", \
                         command=lambda: \
                                 root.focus_get().event_generate('<<Cut>>'))
     
        EditMenu.add_command(label="Copier", \
                         accelerator="Ctrl+C", \
                         command=lambda: \
                                 root.focus_get().event_generate('<<Copy>>'))
     
        EditMenu.add_command(label="Coller", \
                             accelerator="Ctrl+V", \
                             command=lambda: \
                                     root.focus_get().event_generate('<<Paste>>'))
     
        menubar.add_cascade(label="Édition",menu=EditMenu)
        root.config(menu=menubar)    
        nb = ttk.Notebook(root)    
     
        root.update()
     
        def ferme():
            global varGlobal
            for widget in root.winfo_children():
                if isinstance(widget,Toplevel):
                    widget.destroy()
                    varGlobal = 0
     
        def fonc4(event):
            print ("TOP FENETRE")
            print ("Click GAUCHE")
     
        def pointeur(evt):
                    position.configure(text="Clic détecté en X = "+str(evt.x)+", Y = "+str(evt.y))
     
        def fonc3(event):
            global varGlobal
            if varGlobal == 0 :
                print ("EXISTE PAS")            
                varGlobal = 1        
                top = Toplevel(root)
                separator = ttk.Separator(top, orient="horizontal")
                top.overrideredirect(1)
                #print(top.geometry(), root.geometry()) # Affiche 1x1+0+0 1x1+0+0
                top.geometry("{}x{}+{}+{}".format(200, 120, 400, 400))              
            else :
                print ("EXISTE")
                ferme()
     
     
        #print(top.geometry()) # Affiche 1x1+400+400
     
        def fonc1(event):
            ferme()                  
     
        #root.bind("<Button-3>", fonc3)
        #root.bind("<Button-1>", fonc1)
     
        t=""
     
        frame2 = create_frame(nb, t)
        nb.add(frame2, text="new 1")
        tbox2 = Text(frame2, wrap=WORD)
        #print(tbox2)  
     
        nb.pack(expand=YES, fill=BOTH)
     
        position=Label(root,text="Clic détecté en X =''+'','' Y = ")
        position.pack()
        root.bind("<Button-1>", pointeur)    
     
        mainloop()
    Il me manquait pas grand chose pour que ma fenêtre modale soit fonctionnelle. J'aimerais bien arriver à associer une fonction au label.

  11. #11
    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 778
    Points
    36 778
    Par défaut
    Citation Envoyé par Arsene12 Voir le message
    Il me manquait pas grand chose pour que ma fenêtre modale soit fonctionnelle. J'aimerais bien arriver à associer une fonction au label.
    Pour qu'une fenêtre tkinter soit "modale", il faut utiliser .grab_set() (comme indiqué dans le tuto. d'effbot). Et pour associer une fonction à des Labels, il suffit de récupérer le Label correspondant à là où à cliqué l'utilisateur. Ce qui peut se faire en ouvrant la documentation de grid et en regardant ce que font ..grid_location, .grid_slaves,...

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

  12. #12
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Pour qu'une fenêtre tkinter soit "modale", il faut utiliser .grab_set() - W
    J'ai repris mon code avec la fenêtre TopLevel et j'ai rajouté top.grab_set() en dessous de top = Toplevel(root)

    Lorsque cette ligne est commentée, la fenêtre TopLevel se ferme lorsqu'on fait un click droit en dehors.
    Si on la décommente cette action n'est plus possible. Et les positions X et Y restent toujours relatives.

    Merci de m'avoir indiqué le site effbot. Je vais essayer de regarder les exemples plus souvent.
    J'ai découvert un autre site également : programcreek.com

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [GTK+ 3] Création d'une fenêtre modale / Modal Dialog
    Par TANITE dans le forum GTK+ avec C & C++
    Réponses: 1
    Dernier message: 13/10/2014, 08h29
  2. Modifier un champ à partir d'une fenêtre modale
    Par ahoyeau dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 08/03/2005, 16h53
  3. Formulaire dans une fenêtre modale
    Par Amnesiak dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 28/02/2005, 14h25
  4. Supprimer la croix dans une fenêtre modale
    Par AnneOlga dans le forum C++Builder
    Réponses: 3
    Dernier message: 15/01/2004, 14h52
  5. Rendre une fenêtre modale non modale
    Par Smortex dans le forum Composants VCL
    Réponses: 2
    Dernier message: 30/03/2003, 17h56

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