23 Stimmen

Tkinter Raster: So platzieren Sie Widgets, damit sie nicht zusammenkleben

Ich versuche, zwei Label-Widgets zu erstellen, die sich oben links und oben rechts in meiner Test-Benutzeroberfläche befinden. Das Problem ist, dass die Widgets zusammenkleben und ich gerne Platz zwischen ihnen hätte.

In meiner Recherche stieß ich auf Vorschläge, die die Verwendung der Optionen sticky, padx und pady empfehlen. Aber egal welche Argumente ich an .grid() übergebe, ich scheine keinen Raum zwischen meinen Widgets schaffen zu können. Mir ist bewusst, dass unabhängig von der Anzahl der Spalten und Reihen zwischen zwei Widgets, wenn diese Reihen/Spalten leer sind, ist es so, als ob sie nicht existieren und die Widgets zusammengeklebt erscheinen.

Wie kann ich mit der Methode .grid() Widgets positionieren, so dass sie nicht zusammenkleben?

Hier ist mein bisheriger Code:

#!/usr/bin/python
from Tkinter import *

class MyApp:
    def __init__(self, parent):
        self.myParent = parent
        self.main_container = Frame(parent)
        self.main_container.grid(row=0, rowspan=2, column=0, columnspan=4)

        self.top_frame = Frame(self.main_container)
        self.top_frame.grid(row=0, column=0, columnspan=4)

        self.top_left = Frame(self.top_frame)
        self.top_left.grid(row=0, column=0, columnspan=2)

        self.top_right = Frame(self.top_frame)
        self.top_right.grid(row=0, column=2, columnspan=2)

        self.bottom_frame = Frame(self.main_container)
        self.bottom_frame.grid(row=2, column=0, columnspan=4)

        self.top_left_label = Label(self.top_left, text="Oben Links")
        self.top_left_label.grid(row=0, column=0, sticky='W', padx=2, pady=2)

        self.top_right_label = Label(self.top_right, text="Oben Rechts")
        self.top_right_label.grid(row=0, column=4, sticky='E', padx=2, pady=2)

        self.text_box = Text(self.bottom_frame, height=5, width=40)
        self.text_box.grid(row=0, column=0)

root = Tk()
root.title("Test UI")
myapp = MyApp(root)
root.mainloop()

~~Update~~

Ich habe Folgendes versucht, aber es hat nicht funktioniert:

    self.top_left = Frame(self.top_frame)
    self.top_left.grid(row=0, column=0, columnspan=2)
    for c in range(2):
        self.top_left.columnconfigure(c, weight=2)

    self.top_right = Frame(self.top_frame)
    self.top_right.grid(row=0, column=2, columnspan=2)
    for c in range(2):
        self.top_right.columnconfigure(c, weight=2)

76voto

Bryan Oakley Punkte 337213

Du musst grid_columnconfigure verwenden, um den Spalten in der Mitte etwas Gewicht zu geben. Mit mehr Gewicht als den anderen Spalten werden sie sich ausdehnen und zusammenziehen, um jeden zusätzlichen Platz zu füllen, den du hast. In deinem Fall gibt es jedoch wirklich keinen Bedarf, grid zu verwenden. Alles in deinem GUI ist entlang bestimmter Seiten ausgerichtet, für die pack besser geeignet ist.

Ich werde zeigen, wie man sowohl pack als auch grid verwendet, wobei ich mit pack beginne, da es am einfachsten ist. Auch wenn du darauf bestehst, grid zu verwenden, lies den nächsten Abschnitt durch, um zu verstehen, wie man ein großes Layoutproblem in viele kleinere Layoutprobleme aufteilt.

Teile und Herrsche

Der beste Weg, Layouts in Tkinter zu machen, ist "teile und herrsche". Beginne mit den äußersten Widgets und bringe sie genau so auf den Weg, wie du es möchtest. Dann gehst du jedes davon einzeln an.

In deinem Fall hast du ein äußerstes Widget - den Hauptcontainer. Da es das einzige Widget im Fenster ist, ist pack der einfachste Weg, um sicherzustellen, dass es den gesamten Container ausfüllt. Du kannst auch grid verwenden, aber es erfordert etwas mehr Arbeit:

self.main_container = Frame(parent, background="bisque")
self.main_container.pack(side="top", fill="both", expand=True)

Es hilft, deinen Frames vorübergehend distinctive Farben zu geben, damit du sie während der Entwicklung visualisieren kannst. Füge einfach den obigen Code zu deinem __init__ hinzu, führe deine App aus und ändere die Fenstergröße, um sicherzustellen, dass der Hauptframe sich ordnungsgemäß vergrößert und verkleinert.

Dann hast du zwei Frames - top_frame und bottom_frame. Nach ihren Namen und basierend darauf, wie du versucht hast, grid zu verwenden, nehme ich an, dass sie das GUI in x-Richtung füllen sollten. Außerdem gehe ich davon aus, dass der oberste Rahmen eine Art Symbolleiste ist und der untere Rahmen der eigentliche "Haupt"teil deines GUIs ist. Lass uns also das untere Widget den zusätzlichen Platz einnehmen.

Da diese übereinander gestapelt sind, ist pack wieder die natürliche Wahl. Füge den folgenden Code hinzu - und nur den folgen...

2voto

Farhad Maleki Punkte 3057

Hier ist eine einfache Möglichkeit, es zu tun:

  • Entwerfen Sie zuerst Ihre GUI auf Papier oder verwenden Sie ein beliebiges Tool, das für Sie funktioniert
  • Verwenden Sie das Grid-Layout-Manager
  • Wo immer Sie leeren Raum schaffen möchten, verwenden Sie die columnspan- oder rowspan-Eigenschaft des Layouts in Kombination mit der sticky-Eigenschaft. Columnspan oder Rowspan ermöglichen es Ihnen, mehr als eine Zelle des Rasters einem GUI-Komponenten zuzuweisen, und die sticky-Eigenschaft ermöglicht es Ihnen, dieses Element an einer Seite zu fixieren und auf der anderen Seite leeren Raum zu lassen

1voto

A. Rodas Punkte 19571

Wenn Sie bg = "red" sowohl den Konstruktoren von top_left als auch top_right hinzufügen, sehen Sie, wie die Frames in der Mitte feststecken, selbst wenn Sie die sticky Option verwenden. Wenn sie nichts anderes als ein einzelnes Widget enthalten sollen, empfehle ich, sie nicht zu verwenden.

#!/usr/bin/python
from Tkinter import *

class MyApp:
    def __init__(self, parent):
        self.top_left_label = Label(parent, text="Oben Links")
        self.top_left_label.grid(row=0, column=0, padx=2, pady=2, sticky=N+S+W)

        self.top_right_label = Label(parent, text="Oben Rechts")
        self.top_right_label.grid(row=0, column=1, padx=2, pady=2, sticky=N+S+E)

        self.text_box = Text(parent, height=5, width=40)
        self.text_box.grid(row=1, column=0, columnspan=2)

root = Tk()
root.title("Test UI")
myapp = MyApp(root)
root.mainloop()

1voto

James Punkte 21

Lieber spät als nie ;)

"Grid" von Tkinter möchte alles zusammenfügen. Deshalb können Sie keine Zellen überspringen. Sie müssen die Breiten angeben und dann den Text verankern. Ich habe Farbe hinzugefügt, um die Zellen zu markieren. Ich habe die bd in den Rahmen gesetzt. Dann musste ich den Zellen links und rechts eine Breite geben, damit das Grid ihnen Gewicht gibt. Dann Text ankernd West oder Ost. Ich bin mir nicht sicher, warum ich für jede Zelle extra 2 Leerzeichen hinzufügen musste, aber ich dachte, es handele sich um ein Schriftartproblem.

Ich finde, dass Rodas sauberer und einfacher ist, aber ich habe versucht, mich an die von Ihnen gestellten Parameter zu halten.

Pack ist einfacher und schneller für kleine Dinge.

from tkinter import *

class MyApp:
    def __init__(self, parent):
        self.myParent = parent

        self.main_container = Frame(parent, bg="green")
        self.main_container.grid()

        self.top_frame = Frame(self.main_container)
        self.top_frame.grid()

        self.top_left = Frame(self.top_frame, bd=2)
        self.top_left.grid(row=0, column=0)

        self.top_right = Frame(self.top_frame, bd=2)
        self.top_right.grid(row=0, column=2)

        self.top_left_label = Label(self.top_left, bd=2, bg="red", text="Oben Links", width=22, anchor=W)
        self.top_left_label.grid(row=0, column=0)

        self.top_right_label = Label(self.top_right, bd=2, bg="blue", text="Oben Rechts", width=22, anchor=E)
        self.top_right_label.grid(row=0, column=0)

        self.bottom_frame = Frame(self.main_container, bd=2)
        self.bottom_frame.grid(row=2, column=0)

        self.text_box = Text(self.bottom_frame, width=40, height=5)
        self.text_box.grid(row=0, column=0)

root = Tk()
root.title("Test UI")
myapp = MyApp(root)
root.mainloop()

0voto

Farhad Maleki Punkte 3057

Wenn Sie die vollständige Kontrolle über die Platzierung Ihres GUI-Komponenten benötigen, versuchen Sie es mit dem Platzierungs-Layout; ein äußerst verwaltbarer Ansatz besteht darin, Ihre Komponenten in mehreren Frames mit Grid- oder Pack-Layout zu organisieren und dann all diese Frames mit Platzierungs-Layout zu organisieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X