Scroll-"Frame" mit internen Frames

Fragen zu Tkinter.
Antworten
delphinis
User
Beiträge: 16
Registriert: Sonntag 5. Juli 2020, 07:34

Hallo,
ich möchte ein scrollbares Frame erstellen, in welches man unter-Frames einfügen kann. Diese Frames enthalten dann weitere Widgets wie Buttons oder Labels.
Nun hab ich das soweit gebracht, dass es mit mehreren Frames mit jeweils zwei Buttons funktioniert:
Leider kann ich hier kein Bild hochladen um es zu veranschaulichen, aber es funktioniert mit jeweils zwei Buttons in jedem Frame.
Sobald ich aber anstatt zwei buttons zusätzlich noch ein Label auf die selbe Weise einfügen will (siehe auskommentierte Linien im Code) kommt die folgende Fehlermeldung:
"_tkinter.TclError: cannot use geometry manager pack inside . which already has slaves managed by grid"

hier der Code:

Code: Alles auswählen

import tkinter as tk
from tkinter import Tk, RIGHT, BOTH, X, RAISED, GROOVE, YES, messagebox, Canvas
from tkinter import ttk
import traceback

class Window(tk.Frame):
    def __init__(self, aMaster):
        tk.Frame.__init__(self, aMaster)
        self.master = aMaster
        self.framelist = []
        self.master.title("Web tracer")
        container = ttk.Frame(aMaster)
        canvas = tk.Canvas(container)
        scrollbar = ttk.Scrollbar(container, orient="vertical", command=canvas.yview)
        frame = ttk.Frame(canvas)

        frame.bind("<Configure>", lambda e: canvas.configure(scrollregion=canvas.bbox("all")))
        canvas.create_window((0, 0), window=frame, anchor="nw")
        canvas.configure(yscrollcommand=scrollbar.set)
        for i in range(15):
            self.placeFrame(frame, i, "Button" + str(i)).pack()
        container.pack()
        canvas.pack(side="left", fill="both", expand=True)
        scrollbar.pack(side="right", fill="y")
        
    def placeFrame(self, aMaster, aRow, atext):
        frame = ttk.Frame(aMaster)

        button = ttk.Button(frame, text=atext + '-1')
        button.grid(row=aRow, column=0, padx='1', pady='1')
        button2 = ttk.Button(frame, text=atext + '-2')
        button2.grid(row=aRow, column=1, padx='1', pady='1')
        #label = ttk.Label(text=atext)
        #label.grid(row=aRow, column=2, padx='1', pady='1')
        return frame

def main():
    root = tk.Tk()
    app = Window(root)
    root.mainloop()

if __name__ == '__main__':
    main()
    
Sirius3
User
Beiträge: 18265
Registriert: Sonntag 21. Oktober 2012, 17:20

Die Fehlermeldung sagt doch schon deutlich, was Du falsch machst: Die Frames und das canvas wird mit pack in root positioniert, das Label dagegen mit grid.
Das ist übrigens sehr undurchsichtig. Du hast eine Klasse Window, die ein Frame ist, dessen Eigenschaften aber gar nicht benutzt werden, sondern Du packst alles, was Du da in __init__ erzeugst in aMaster was ja root ist. In placeFrame dagegen, wird gar keine Frame positioniert, sondern ein neuer Frame erzeugt, mit zwei Knöpfen, das Label aber packst Du implizit nach root, was man eh nicht machen sollte, weil es genau zu solchen Fehlern führt, die schwer zu durchschauen sind. Die row in den grid-Aufrufen ist quatsch, da Du ja jede Knopf-Zeile in einen eigenen Frame packst.

framelist wird nicht verwendet. Datentypen gehören nicht in Variablennamen, das sollte einfach frames heißen, oder konkreter, frames_for_buttons, o.ä..

Methoden schreibt man wie Variablen komplett klein. Was soll das a bei aMaster? Was soll das a bei aRow oder atext? Warum wird atext richtig geschrieben, die ganzen anderen a-Variablen aber nicht?

Lass das a weg, denn es verwirrt nur, und ob das ursprünglich mal ein Argument war oder nicht, spielt keine Rolle.
Zuletzt geändert von Sirius3 am Freitag 10. Juli 2020, 09:24, insgesamt 1-mal geändert.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wenn du Bilder hochladen willst, musst du sie bei einem externen Hoster (zb imgur) hochladen, und hier in die Tags packen. Ist leider etwas umständlich.

Zu deiner Frage: die Fehlermeldung ist doch sehr deutlich: du mischst zwei Layout verfahren, und das geht nicht. Der Grund ist vermutlich, das du dem Label keinen expliziten parent gibst, und das dann am root aufgehangen wird. Und Root nutzt pack.
Antworten