Seite 1 von 1

Rechtsklick Menu

Verfasst: Mittwoch 5. Februar 2020, 15:10
von Fire Spike
Hallo ich habe 2 Fragen:
  • Ich habe ein Entry.
    Wie kann ich jetzt machen das wenn ich mit rechts auf das Entry klicke ein Menu erscheint?
  • Ich habe ein Fenster in dem ich 3 verschiedene Diagramme anzeigen will. Da die sehr gross sind würde ich gerne die so scrollen dass immer nur eins sichtbar ist. Wie kann ich das machen?
    Ich zeige die Diagramme so an:

    Code: Alles auswählen

    canvas = FigureCanvasTkAgg(fig, master=self)
    canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
Ich hoffe ihr könnt mir helfen :wink:
Danke im Voraus :)

Re: Rechtsklick Menu

Verfasst: Mittwoch 5. Februar 2020, 15:19
von __deets__
Bezueglich des Rechtsklicks musst du mal in der Dokumentation nach Event-Binding suchen, da wird das dann erklaert.

Re: Rechtsklick Menu

Verfasst: Mittwoch 5. Februar 2020, 17:55
von Fire Spike
OK. :

Code: Alles auswählen

self.bind("<Button-3>", blabla)
Und wie mache ich das Menu?

Re: Rechtsklick Menu

Verfasst: Mittwoch 5. Februar 2020, 18:02
von __deets__
Indem du ein modales Fenster baust das du an der Stelle des Mauszeigers anzeigst. Und dann all die Sonderfaelle beachtest, wie zB was passiert wenn das Entry am Rande des Bildschirmes irgendwo ist, und das Menue irgendwo auftauchen wuerde, wo man es gar nicht mehr bedienen kann. Ein Start waere zB hier zu finden: https://stackoverflow.com/questions/120 ... ntext-menu

Re: Rechtsklick Menu

Verfasst: Freitag 7. Februar 2020, 18:11
von Fire Spike
Ich habe mal probiert das umzusetzen, aber ich scheitere an den Bindings, denn das vom root definiert auch das vom Menu.
Ich weiss nicht wieso das es nicht funktioniert.
Was mache ich falsch? :?:

So binde ich das Event:

Code: Alles auswählen

self.rklick = Rechtsklick(self)
binding = self.bind_all("<Button-1>", self.rklick.verstecken)
self.rklick.unbind(binding)
self.eingabe.bind("<Button-3>", self.rklick.popup)
So definiere ich das Rechtsklickmenu:

Code: Alles auswählen

class Rechtsklick():
    def __init__(self, master):
        self.master = master
        self.aMenu = tk.Menu(self.master, tearoff=0)
        self.aMenu.config(bg="white")
        self.aMenu.add_command(label="löschen", command=self.löschen)
        self.aMenu.add_command(label="Alles löschen", command=self.alles_löschen)

    def löschen(self):
        print("gelöscht")

    def alles_löschen(self):
        print("alles gelöscht")

    def popup(self, event):
        self.aMenu.post(event.x_root, event.y_root)
    
    def verstecken(self, event):
        self.aMenu.unpost()
    
    def unbind(self, binding):
        self.aMenu.unbind(binding)

Re: Rechtsklick Menu

Verfasst: Mittwoch 12. Februar 2020, 16:34
von Fire Spike
Könnt ihr mir bitte helfen?🙏🙏🙏
Wahrscheinlich habe ich genau eine Zeile zu wenig :oops:

Re: Rechtsklick Menu

Verfasst: Mittwoch 12. Februar 2020, 17:34
von __deets__
Dann bau bitte ein komplett lauffaehiges Beispiel, oder poste deinen gesamten Code (der natuerlich auch laeuffaehig sein muss).

Re: Rechtsklick Menu

Verfasst: Mittwoch 12. Februar 2020, 17:41
von Fire Spike
Mein ganzer Code hat 473 Zeilen, willst du den wirklich, oder soll ich ein Beispiel machen?

Re: Rechtsklick Menu

Verfasst: Mittwoch 12. Februar 2020, 18:01
von __deets__
Das Internet ist gross, 473 Zeilen Code passen da noch gerade so rein. Der entscheidende Punkt ist, dass es *funktionieren* muss, ohne das man da irgendwie dran rumfummeln muss (mit Ausnahme des Rechts-Klicks natuerlich). Wenn das nicht so ohne weiteres moeglich ist (weil du ZB auf GPIO eines PI zugreifst), dann bau ein Beispiel.

Re: Rechtsklick Menu

Verfasst: Mittwoch 12. Februar 2020, 21:33
von Fire Spike
Ein Beispiel weil der original Code Exceldateien braucht.

Code: Alles auswählen

import tkinter as tk

class Rechtsklick():
    def __init__(root, master):
        root.master = master
        root.aMenu = tk.Menu(root.master, tearoff=0)
        root.aMenu.config(bg="white")
        root.aMenu.add_command(label="löschen", command=root.löschen)
        root.aMenu.add_command(label="Alles löschen", command=root.alles_löschen)

    def löschen(root):
        print("gelöscht")

    def alles_löschen(root):
        print("alles gelöscht")

    def popup(root, event):
        root.aMenu.post(event.x_root, event.y_root)
    
    def verstecken(root, event):
        root.aMenu.unpost()
    
    def unbind(root, binding):
        root.aMenu.unbind(binding)
        
def main():
    root = tk.Tk()
    root.config(bg="white")
    rklick = Rechtsklick(root)
    binding = root.bind_all("<Button-1>", rklick.verstecken)
    rklick.unbind(binding)
    
    tk.Label(root, text="Name", fg="darkblue", bg="white", font=('arial', 15)).grid(row=0, column=0, sticky="w")
    root.name_eingabe = tk.Entry(root, bg="white", width=30, font=('arial', 13))
    root.name_eingabe.grid(row=1, column=0, sticky="w")
    root.name_eingabe.bind("<Button-3>", rklick.popup)
    
    tk.Label(root, text="Vorname", fg="darkblue", bg="white", font=('arial', 15)).grid(row=2, column=0, sticky="w")
    root.first_name_eingabe = tk.Entry(root, bg="white", width=30, font=('arial', 13))
    root.first_name_eingabe.grid(row=3, column=0, sticky="w")
    root.first_name_eingabe.bind("<Button-3>", rklick.popup)
    root.mainloop()
    
if __name__ == "__main__":
    main()
Es sind in Wirklichkeit viel mehr Eingabefelder darum das bind_all.

Re: Rechtsklick Menu

Verfasst: Mittwoch 12. Februar 2020, 21:57
von __deets__
Neben dem vergurkten root, das stattdessen ein self sein sollte, liegt das Problem in deinem rklick.unbind - damit entfernst du augenscheinlich das Binding fuer den Menueeintrag. So funktiontiert es fuer mich:

Code: Alles auswählen

import tkinter as tk

class Rechtsklick():
    def __init__(self, master):
        self.master = master
        self.aMenu = tk.Menu(master, tearoff=0)
        self.aMenu.config(bg="white")
        self.aMenu.add_command(label="löschen", command=self.löschen)
        self.aMenu.add_command(label="Alles löschen", command=self.alles_löschen)

    def löschen(self):
        print("gelöscht")

    def alles_löschen(self):
        print("alles gelöscht")

    def popup(self, event):
        self.aMenu.post(self.master.winfo_pointerx(), self.master.winfo_pointery())

    def verstecken(self, event):
        self.aMenu.unpost()

    def unbind(self, binding):
        self.aMenu.unbind(binding)


def main():
    root = tk.Tk()
    root.config(bg="white")
    rklick = Rechtsklick(root)
    #binding = root.bind_all("<Button-1>", rklick.verstecken)
    #rklick.unbind(binding)

    tk.Label(root, text="Name", fg="darkblue", bg="white", font=('arial', 15)).grid(row=0, column=0, sticky="w")
    root.name_eingabe = tk.Entry(root, bg="white", width=30, font=('arial', 13))
    root.name_eingabe.grid(row=1, column=0, sticky="w")
    root.name_eingabe.bind("<Button-3>", rklick.popup)

    tk.Label(root, text="Vorname", fg="darkblue", bg="white", font=('arial', 15)).grid(row=2, column=0, sticky="w")
    root.name_eingabe = tk.Entry(root, bg="white", width=30, font=('arial', 13))
    root.name_eingabe.grid(row=3, column=0, sticky="w")
    root.name_eingabe.bind("<Button-3>", rklick.popup)
    root.mainloop()

if __name__ == "__main__":
    main()

Re: Rechtsklick Menu

Verfasst: Donnerstag 13. Februar 2020, 16:50
von Fire Spike
so muss ich ja bei jedem Objekt

Code: Alles auswählen

bind("<Button-1>", self.rklick.verstecken)
hinzufügen und wie gesagt: das sind sehr viele :shock:

Re: Rechtsklick Menu

Verfasst: Donnerstag 13. Februar 2020, 16:56
von __deets__
Ich glaube eher das unbiding ist das Problem. Aber wenn es auf die eine Art geht, und auf die andere nicht - was willst du sonst machen?

Re: Rechtsklick Menu

Verfasst: Donnerstag 13. Februar 2020, 17:01
von Sirius3
@Fire Spike: wenn man etwas an sehr vielen Stellen im Code gleichartig ändern muß, dann ist das ein Zeichen dafür, dass man besser eine Funktion schreibt.

Re: Rechtsklick Menu

Verfasst: Donnerstag 13. Februar 2020, 17:09
von Fire Spike
wie würdest den du Entrys, Text, Button und Label mit einer Funktion diese Binding hinzufügen?

Re: Rechtsklick Menu

Verfasst: Donnerstag 13. Februar 2020, 17:14
von __deets__
Ohne irgendwas anderes zu machen geht es nicht. Du kannst zB eine Liste der Kontext-Objekte verwalten, und dann fuer die dann die Bindung in einem Rutsch (aber eben mit einzelnen calls) anlegen. Oder du kannst versuchen, nur auf dem toplevel-Objekt (also dem Fenster) ein Rechtsklick zu binden. Wenn der durchgeht, weil kein anderes Objekt davor ihn konsumiert (was eigentlich so sei sollte AFAIK), dann kannst du probieren, das passende Kind zum Rechtsklick anhand der Koordinaten zu finden, und damit dann weiter arbeiten.

Re: Rechtsklick Menu

Verfasst: Donnerstag 13. Februar 2020, 17:58
von Sirius3
Wie sieht denn Dein Code jetzt aus?