mehrere toplevel gleichzeitig fokussieren

Fragen zu Tkinter.
Antworten
silvapuer
User
Beiträge: 7
Registriert: Dienstag 11. Februar 2020, 16:41

Hi,
ich habe ein Programm geschrieben, das eine eigene Bildschirmtastatur beinhaltet. mein Problem ist, dass wenn ich den Curser in die Console der GUI setze und dann auf einen Button auf dem Tastatur-Toplevel klicke, das Hauptfenster mit der Console den Fokus verliert und das Tastaturtoplevel fokusiert wird. dadurch erscheint der angeklickte Buchstabe nicht in der Console.

hier mein vereinfachter Code:

Code: Alles auswählen

from tkinter import Tk, ttk, Toplevel, Menu, Frame, Label, Text, Scrollbar, Button, INSERT, NS, EW, Variable
from sympy import *
#from sympy.plotting import *
import keyboard

class Hauptfenster:
    active_tab_index = 0
    active_tab = "" 
    def __init__(self, master):
        self.master = master
        master.title("Hauptfenster")

        #menüleiste erstellen
        self.menubar = Menu(self.master, bg="#000000")
        self.filemenu = Menu(self.menubar, tearoff=0)
        self.filemenu.add_command(label="Tastatur", command=self.show_tastatur)
        self.menubar.add_cascade(label="Anzeigen", menu=self.filemenu)
        self.helpmenu = Menu(self.menubar, tearoff=0)
        self.helpmenu.add_command(label="About...", command=None)
        self.helpmenu.add_separator()
        self.helpmenu.add_command(label="Exit", command=self.master.quit)
        self.menubar.add_cascade(label="Help", menu=self.helpmenu)
        self.master.config(menu=self.menubar)
        
        #notebook ...
        self.tabs = ttk.Notebook(master)
        self.tabs.pack()       
        # ... mit tabs erstellen
        self.editor_frame = Frame(self.tabs)
        self.editor = Editor(self.editor_frame)
        self.second = Frame(self.tabs)
        self.second_label=Label(self.second, text="second Tab (needed later)")
        self.second_label.pack()
        self.third = Frame(self.tabs)
        self.third_label=Label(self.third, text="third Tab (needed later)")
        self.third_label.pack()
        self.fourth = Frame(self.tabs)
        self.fourth_label=Label(self.fourth, text="fourth Tab (needed later)")
        self.fourth_label.pack()
        #tabs zu Notebook hinzufügen -> visualisieren
        self.tabs.add(self.editor_frame, text="EDITOR")
        self.tabs.add(self.second, text="2")
        self.tabs.add(self.third, text="3")
        self.tabs.add(self.fourth, text="4")
        self.tabs.bind("<<NotebookTabChanged>>", self.tab_changed)
    
    def show_tastatur(self):
        self.tastatur=Tastatur(self.master)
    
    def tab_changed(self, *event):
        self.active_tab_index = self.tabs.index("current")
        self.active_tab = self.tabs.tab(self.active_tab_index,"text")
        if Tastatur.OPENED: self.tastatur.update(ati=self.active_tab_index, atn=self.active_tab)

class Tastatur:
    OPENED = True
    NAME = "Tastatur"
    
    def __init__(self, master):
        self.master = master
        self.tastatur_tl = Toplevel(self.master)
        self.tastatur_tl.title(self.NAME)
        self.tastatur_tl.protocol("WM_DELETE_WINDOW", self.close)
        #BUTTONDICT beinhaltet alle momentan gebrauchten Tasten.
        self.BUTTONDICT = ({"None":{"command":self.bklicked(""), "text":" "},
                            "0":{"command":self.bklicked("0"), "text":"0"},
                            "1":{"command":self.bklicked("1"), "text":"1"},
                            "2":{"command":self.bklicked("2"), "text":"2"},
                            "3":{"command":self.bklicked("3"), "text":"3"},
                            "4":{"command":self.bklicked("4"), "text":"4"},
                            "5":{"command":self.bklicked("5"), "text":"5"},
                            "6":{"command":self.bklicked("6"), "text":"6"},
                            "7":{"command":self.bklicked("7"), "text":"7"},
                            "8":{"command":self.bklicked("8"), "text":"8"},
                            "9":{"command":self.bklicked("9"), "text":"9"},
                            "A":{"command":self.bklicked("A"), "text":"A"},
                            "B":{"command":self.bklicked("B"), "text":"B"},
                            "C":{"command":self.bklicked("C"), "text":"C"},
                            "D":{"command":self.bklicked("D"), "text":"D"},
                            "E":{"command":self.bklicked("E"), "text":"E"},
                            "F":{"command":self.bklicked("F"), "text":"F"},
                            "G":{"command":self.bklicked("G"), "text":"G"},
                            "H":{"command":self.bklicked("H"), "text":"H"},
                            "I":{"command":self.bklicked("I"), "text":"I"},
                            "J":{"command":self.bklicked("J"), "text":"J"},
                            "K":{"command":self.bklicked("K"), "text":"K"},
                            "L":{"command":self.bklicked("L"), "text":"L"},
                            "M":{"command":self.bklicked("M"), "text":"M"},
                            "N":{"command":self.bklicked("N"), "text":"N"},
                            "O":{"command":self.bklicked("O"), "text":"O"},
                            "P":{"command":self.bklicked("P"), "text":"P"},
                            "Q":{"command":self.bklicked("Q"), "text":"Q"},
                            "R":{"command":self.bklicked("R"), "text":"R"},
                            "S":{"command":self.bklicked("S"), "text":"S"},
                            "T":{"command":self.bklicked("T"), "text":"T"},
                            "U":{"command":self.bklicked("U"), "text":"U"},
                            "V":{"command":self.bklicked("V"), "text":"V"},
                            "W":{"command":self.bklicked("W"), "text":"W"},
                            "X":{"command":self.bklicked("X"), "text":"X"},
                            "Y":{"command":self.bklicked("Y"), "text":"Y"},
                            "Z":{"command":self.bklicked("Z"), "text":"Z"},
                            "!":{"command":self.bklicked("exclm"), "text":"!"},
                            "?":{"command":self.bklicked("quest"), "text":"?"},
                            "komma":{"command":self.bklicked("komma"), "text":","},
                            "gleich":{"command":self.bklicked("gleich"), "text":"="},
                            "plus":{"command":self.bklicked("plus"), "text":"+"},
                            "minus":{"command":self.bklicked("minus"), "text":"-"},
                            "mal":{"command":self.bklicked("mal"), "text":"\u22C5"},
                            "durch":{"command":self.bklicked("durch"), "text":":"},
                            "hoch":{"command":self.bklicked("hoch"), "text":"^"},
                            "wurzel":{"command":self.bklicked("wurzel"), "text":"\u221A"},
                            "sinus":{"command":self.bklicked("sinus"), "text":"sin( )"},
                            "cosinus":{"command":self.bklicked("cosinus"), "text":"cos( )"},
                            "tangens":{"command":self.bklicked("tangens"), "text":"tan( )"},
                            "logarithmus":{"command":self.bklicked("logarithmus"), "text":"log( )"},
                            "EXP":{"command":self.bklicked("EXP"), "text":"\u22C5"+"10^( )"},
                            "EXE":{"command":self.bklicked("EXE"), "text":"EXE"},
                            "f(x)":{"command":self.bklicked("fx"), "text":"f(x)"},
                            "x":{"command":self.bklicked("x"), "text":"x"},
                            "r(theta)":{"command":self.bklicked("rtheta"), "text":"f(\u03b8)"},
                            "theta":{"command":self.bklicked("theta"), "text":"\u03b8"},
                          })
            
        self.buttonlist = Variable(self.master)
        if Hauptfenster.active_tab_index == 0: self.buttonlist.set(Editor.buttonlist)
        elif Hauptfenster.active_tab_index == 1: self.buttonlist.set(Second.buttonlist)
        elif Hauptfenster.active_tab_index == 2: self.buttonlist.set(Third.buttonlist)
        elif Hauptfenster.active_tab_index == 3: self.buttonlist.set(Fourth.buttonlist)
        else: self.buttonlist.set([])

        co = ro = 0
        for button in self.buttonlist.get():
            b_info = self.BUTTONDICT.get(button)
            b = Button(self.tastatur_tl, text=b_info.get("text"), command=b_info.get("command"), width=6)
            b.grid(column=co, row=ro)
            ro += 1
            if ro >= 4:
                ro=0
                co += 1

    def close(self):
        self.OPENED = False
        print("tastatur wurde geschlossen!")
        self.tastatur_tl.destroy()

    def update(self, ati, atn):
        self.active_tab_index = ati
        self.active_tab_name = atn
        self.NAME = "Tastatur ({0})".format(self.active_tab_name)

        if self.OPENED:
            self.tastatur_tl.title(self.NAME)
            for widget in self.tastatur_tl.winfo_children(): #destroys all widgets in tastatur_tl
                widget.destroy()
            
            self.buttonlist = Variable(self.master)
            if self.active_tab_index == 0: self.buttonlist.set(Editor.buttonlist)
            elif self.active_tab_index == 1: self.buttonlist.set(Second.buttonlist)
            elif self.active_tab_index == 2: self.buttonlist.set(Third.buttonlist)
            elif self.active_tab_index == 3: self.buttonlist.set(Fourth.buttonlist)
            else: self.buttonlist = []

            co = ro = 0
            for button in self.buttonlist.get():
                b_info = self.BUTTONDICT.get(button)
                b = Button(self.tastatur_tl, text=b_info.get("text"), command=b_info.get("command"), width=6)
                b.grid(column=co, row=ro)

                ro += 1
                if ro >= 4:
                    ro=0
                    co += 1
                
    def bklicked(self, button):
        #keyboard.press_and_release(button) dafür müste allerdings der fokus in der konsole bleiben
        #Hauptfenster.tabs.editor.console.insert(button) alternative? aber wie kann ich die Konsole ansprechen? so wie es hier ist, funktioniert es nicht! :(
        pass

class Editor:
    buttonlist = ["A","H","O","V","B","I","P","W","C","J","Q","X","D","K","R","Y","E","L","S","Z","F","M","T","!","G","N","U","?","None","None","None","None","7","4","1","komma","8","5","2","0","9","6","3","EXP","hoch","mal","plus","gleich","wurzel","durch","minus","EXE","logarithmus","sinus", "cosinus","tangens"]
    
    def __init__(self, master):
        self.master = master
        self.console = Text(self.master, height=10, width=50, bd=1)
        self.scroll = Scrollbar(self.master, orient="vertical", command=self.console.yview)
        self.console.tag_configure("tag_right", justify="right")
        self.console.config(yscrollcommand=self.scroll.set)
        self.console.grid(column=0, row=0)
        self.console.focus()
        self.scroll.grid(column=1,row=0, sticky=NS)

class Second:
    buttonlist = ["f(x)","x","r(theta)","theta","7","4","1","komma","8","5","2","0","9","6","3","EXP","wurzel","durch","plus","gleich","hoch","mal","minus","EXE","logarithmus","sinus", "cosinus","tangens"]
    pass

class Third:
    buttonlist = ["7","4","1","komma","8","5","2","0","9","6","3","EXE"]
    pass

class Fourth:
    buttonlist = ["7","4","1","komma","8","5","2","0","9","6","3","EXE"]
    pass

root = Tk()
window = Hauptfenster(root)
root.mainloop()

der code ist debugfertig, da könnt ihr euch ein Bild davon machen, wie ich es meine...

oder gibt es ein besseres widget als das Toplevel um die Tastatur umzusetzen?
sie soll aber weiterhin frei beweglich sein, also frei platzierbar...

Hauptfrage: Wie bekomm ich es hin, dass wenn ich auf einen Button der Tastatur klicke das entsprechende Zeichen auch in der console (also dem Textfenster) angezeigt wird?
danke für eure hilfe :)
Antworten