Scrollbar verschwindet, wenn Hauptfenster verkleinert wird

Fragen zu Tkinter.
Antworten
woto
User
Beiträge: 9
Registriert: Mittwoch 15. Juni 2022, 12:55

Hallo zusammen,
ich habe folgendes Problem:
Mein Testprogramm beinhaltet ein Canvas mit linkseitiger Scrollbar.
Wenn ich das Fenster mit der Maus verkleinere, geht die Scrollbar quasi nicht mit und verschwindet dadurch.
Ich denke, dass der Canvas nicht an das Hauptfenster gebunden ist. Was ist an dem Code falsch?

Hier der Code:

Code: Alles auswählen

import tkinter

class MyView(tkinter.Frame):
    def __init__(self, master=None, data=None):
        super().__init__(master)
            
        self.grid(sticky="nsew")

        ##################################################################################
        self.canvas = tkinter.Canvas(self, width=1000, height=550)
        self.scrollbar = tkinter.Scrollbar(self, orient="vertical", command=self.canvas.yview)
        self.scrollable_frame = tkinter.Frame(self.canvas)
        
        self.scrollable_frame.bind(
            "<Configure>",
            lambda e: self.canvas.configure(
                scrollregion=self.canvas.bbox("all")
            )
        )

        self.canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")
        self.canvas.configure(yscrollcommand=self.scrollbar.set)

        self.canvas.grid(row=0, column=0, sticky="nsew")
        self.scrollbar.grid(row=0, column=1, sticky="ns")

        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)

    

# Beispiel für die Verwendung der Klasse
if __name__ == "__main__":
    root = tkinter.Tk()
    root.title("Datenkacheln")
    screenHeight = root.winfo_screenheight()
    screenWidth = root.winfo_screenwidth()
    sizeX = 1020
    sizeY = 580
    
    posX = (screenWidth // 2) - (sizeX // 2)
    posY = (screenHeight // 2) - (sizeY // 2)
    root.geometry(f"{sizeX}x{sizeY}+{posX}+{posY}")
    
    app = MyView(master=root)
    root.mainloop()
VG Woto
woto
User
Beiträge: 9
Registriert: Mittwoch 15. Juni 2022, 12:55

Ich habe in den Frame jetzt mal etwas reingeschrieben, damit man die Scrollbar besser sieht:

Code: Alles auswählen

import tkinter

class MyView(tkinter.Frame):
    def __init__(self, master=None, data=None):
        super().__init__(master)
            
        self.grid(sticky="nsew")

        ##################################################################################
        self.canvas = tkinter.Canvas(self, width=1000, height=550)
        self.scrollbar = tkinter.Scrollbar(self, orient="vertical", command=self.canvas.yview)
        self.scrollable_frame = tkinter.Frame(self.canvas)
        
        self.scrollable_frame.bind(
            "<Configure>",
            lambda e: self.canvas.configure(
                scrollregion=self.canvas.bbox("all")
            )
        )

        self.canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")
        self.canvas.configure(yscrollcommand=self.scrollbar.set)

        self.canvas.grid(row=0, column=0, sticky="nsew")
        self.scrollbar.grid(row=0, column=1, sticky="ns")

        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)

        for i in range(50):
            tkinter.Label(self.scrollable_frame, text=f"Label {i}").pack()
    

# Beispiel für die Verwendung der Klasse
if __name__ == "__main__":
    root = tkinter.Tk()
    root.title("Datenkacheln")
    screenHeight = root.winfo_screenheight()
    screenWidth = root.winfo_screenwidth()
    sizeX = 1020
    sizeY = 580
    
    posX = (screenWidth // 2) - (sizeX // 2)
    posY = (screenHeight // 2) - (sizeY // 2)
    root.geometry(f"{sizeX}x{sizeY}+{posX}+{posY}")
    
    app = MyView(master=root)
    root.mainloop()
Benutzeravatar
__blackjack__
User
Beiträge: 13919
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@woto: Der Frame passt sich nicht der Grösse an.

`geometry()` macht keinen Sinn. Die Fenstergrösse ergibt sich aus dem Inhalt. Und man sollte auch nicht selbst die Position von Fenstern festlegen wollen. Das macht die Fensterverwaltung auf dem System des Benutzers. Die weiss a) wo Platz ist, und b) was der Benutzer möchte.

Widgets layouten sich nicht selbst. Das macht kein bestehendes Widget, damit sollte man bei eigenen nicht anfangen.

Wenn es für Werte mit einer festen Bedeutung im `tkinter`-Modul eine Konstante gibt, sollte man die benutzen, statt eine Zeichenkette.

Code: Alles auswählen

import tkinter


class View(tkinter.Frame):
    def __init__(self, master):
        super().__init__(master)
        self.canvas = tkinter.Canvas(self, width=1000, height=550)
        self.scrollbar = tkinter.Scrollbar(
            self, orient=tkinter.VERTICAL, command=self.canvas.yview
        )
        self.scrollable_frame = tkinter.Frame(self.canvas)

        self.scrollable_frame.bind(
            "<Configure>",
            lambda e: self.canvas.configure(
                scrollregion=self.canvas.bbox(tkinter.ALL)
            ),
        )
        self.canvas.create_window(
            (0, 0), window=self.scrollable_frame, anchor=tkinter.NW
        )
        self.canvas.configure(yscrollcommand=self.scrollbar.set)

        self.canvas.grid(row=0, column=0, sticky=tkinter.NSEW)
        self.scrollbar.grid(row=0, column=1, sticky=tkinter.NS)

        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)

        for i in range(50):
            tkinter.Label(self.scrollable_frame, text=f"Label {i}").pack()


def main():
    root = tkinter.Tk()
    root.title("Datenkacheln")

    view = View(root)
    view.pack(expand=True, fill=tkinter.BOTH)

    root.mainloop()


if __name__ == "__main__":
    main()
“I am Dyslexic of Borg, Your Ass will be Laminated” — unknown
woto
User
Beiträge: 9
Registriert: Mittwoch 15. Juni 2022, 12:55

Hallo __blackjack__,
vielen Dank für deine Antwort. :D
Deine Anpassungen werde ich heute mal ausprobieren.
VG woto
Antworten