Ich versuche, die Größe eines Frames in tkinter zu ändern, aber die Breite ändert sich nicht und die Funktion winfo_width () gibt 1 zurück. Wie kann ich das beheben?

from tkinter import *

root = Tk()
root.geometry('400x300')
Frame = LabelFrame(root, text="Test", width = 200)
Frame.grid(row = 0, column = 0)
label = Label(Frame, text = '').grid(row = 0, column=0)


print(Frame.winfo_width()) #output is 1 instead of 200

root.mainloop()
2
Artem 7 Feb. 2020 im 17:50

3 Antworten

Beste Antwort

Wie die anderen bereits darauf hingewiesen haben, wie Sie mit grid_propagate() einen Rahmen mit statischer Größe festlegen, werde ich Ihnen zeigen, wie Sie Ihren Rahmen so einrichten, dass die Größe automatisch geändert wird.

Sie müssen der Zeile und Spalte mitteilen, dass der Frame erweitert werden soll. Dies erfolgt mit columnconfigure() und rowconfigure(). Dann müssen Sie dem Rahmen mitteilen, dass er mit sticky='nsew' an allen Seiten haften soll. Das Hinzufügen von Widgets zum Frame unterscheidet sich nicht von anderen Containern. Sagen Sie dem Widget einfach, dass es sich im Frame befinden soll.

Ein potenzielles Problem, das ich sehe, ist, dass Sie Frame() in dieser Zeile überschreiben: Frame = LabelFrame(root, text="Test", width = 200). Dies ist ein gutes Beispiel, warum Sie den Import * nicht verwenden sollten. Führen Sie stattdessen import tkinter as tk aus und verwenden Sie das Präfix tk. für alles, was es benötigt.

Beispiel:

import tkinter as tk

root = tk.Tk()
root.geometry('400x300')
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
frame = tk.LabelFrame(root, text='Test', width=200)
frame.grid(row=0, column=0, sticky='nsew')
label = tk.Label(frame, text='label').grid(row=0, column=0)
root.mainloop()

Ergebnisse:

enter image description here

Aktualisieren:

Wenn Sie etwas Statisches wollen, stellen Sie sicher, dass Sie sowohl Höhe als auch Breite definieren. Wenn Sie nur das eine oder das andere definieren, wird der Rahmen im Fenster nicht angezeigt.

Ein testbares Beispiel für eine statische Rahmengröße:

import tkinter as tk

root = tk.Tk()
root.geometry('400x300')
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
frame = tk.LabelFrame(root, text='Test', height=200, width=200)
frame.grid(row=0, column=0)
frame.grid_propagate(False)
label = tk.Label(frame, text='label').grid(row=0, column=0)

root.mainloop()

Ergebnisse:

enter image description here

2
Mike - SMT 7 Feb. 2020 im 15:51

Die Breite gibt 1 zurück, da das Fenster noch nicht gezeichnet wurde. Die tatsächliche Breite hängt vom gezeichneten Fenster ab, da die tatsächliche Breite von vielen Faktoren abhängt, die vor dem tatsächlichen Zeichnen des Fensters nicht bekannt sind.

Wenn Sie root.update() aufrufen, bevor Sie Frame.winfo_width() aufrufen, um das Zeichnen des Fensters zu erzwingen, wird der tatsächliche Wert angezeigt.

Diese Frage ist zu weit gefasst, um sie zu beantworten. Normalerweise ist es nicht ratsam, die Breite eines Rahmens direkt einzustellen. Standardmäßig passt Tkinter die Größe eines Frames automatisch an seine untergeordneten Elemente an. Eine Möglichkeit, den Rahmen breiter zu machen, besteht darin, weitere Widgets hinzuzufügen.

Die Breite kann auch davon abhängen, wie sie zur Anzeige hinzugefügt wird - ob Sie pack oder grid oder place verwenden und wie Sie sie konfiguriert haben. Eine andere Möglichkeit, den Rahmen breiter zu machen, besteht darin, nicht standardmäßige Optionen zu verwenden, die dazu führen, dass der Rahmen wächst oder schrumpft, um dem ihm zugewiesenen Platz zu entsprechen.

Wenn Sie eine explizite Größe angeben und die automatische Größenänderung von tkinter ignorieren möchten, können Sie dies tun, indem Sie die Geometrieausbreitung deaktivieren und dann die Parameter width und height für den Frame festlegen. Je nachdem, ob Sie grid oder pack verwenden, können Sie grid_propagate oder pack_propagate mit einem False Argument aufrufen, um die Weitergabe zu deaktivieren (place unterstützt keine Geometrieausbreitung).

Beachten Sie, dass das Deaktivieren der Geometrieausbreitung normalerweise die am wenigsten wünschenswerte Lösung ist, da Sie viel mehr Arbeit benötigen, um eine reaktionsfähige Benutzeroberfläche zu erstellen. Der beste Weg, um eine Benutzeroberfläche mit tkinter zu entwerfen, besteht darin, sich auf die Größe der inneren Widgets zu konzentrieren und tkinter die effizienteste Größe für Frames und das Fenster selbst berechnen zu lassen.

3
Bryan Oakley 7 Feb. 2020 im 15:55

Ihr Frame kann sich basierend auf den darauf befindlichen Widgets im Raster ausbreiten und hat keine festen Abmessungen.

Die Ausgabe von 1 ist darauf zurückzuführen, dass sich auf dem Frame nur ein leeres Label befindet. (Es würde immer noch 1 anzeigen, wenn es kein Label gäbe.)

Um die Ausgabe als 200 zu erhalten, setzen Sie das Flag grid_propagate wie folgt auf False ( nur nach dem Festlegen der Parameter für Höhe und Breite):

frame = Frame(..., width=200)
frame.grid(row=0, column=0)
frame.grid_propagate(False)
1
FrainBr33z3 7 Feb. 2020 im 15:01