Seite 1 von 1

Hilfe zu columnconfigure und columnspan

Verfasst: Donnerstag 30. Juni 2022, 10:31
von Nobuddy
Hallo,
benötige Eure Hilfe zu columnconfigure und columnspan.
Ich habe dazu einen Testcode, den ich am Ende bereitstellen werde.

In dem Beispiel hat die erste bis dritte Reihe 4 Spalten, die Breite der Widgets ist 10.
Die vierte bis fünfte Reihe hat 6 Spalten, die Breite der Widgets ist 10.
Ab der sechsten Reihe sind es 8 Spalten und die Breite der Widgets ist 40.
Die Widgets sollen von links nach rechts aneinander liegen.

Ich habe schon einiges ausprobiert, komme aber nicht auf das gewünschte Ergebnis.
Hoffe, Ihr könnt mir dabei helfen!

Hier der Beispielcode:

Code: Alles auswählen

import tkinter as tk

class AutoScrollbar(tk.Scrollbar):

	def set(self, low, high):
		if float(low) <= 0.0 and float(high) >= 1.0:
			self.tk.call("grid", "remove", self)
		else:
			self.grid()
		tk.Scrollbar.set(self, low, high)

	def pack(self, **kw):
		raise (TclError,"pack cannot be used with \
		this widget")

	def place(self, **kw):
		raise (TclError, "place cannot be used  with \
		this widget")

root = tk.Tk()

yscrollbar = AutoScrollbar(root)

yscrollbar.grid(row=0, column=1, sticky=tk.NS)

xscrollbar = AutoScrollbar(root, orient=tk.HORIZONTAL)

xscrollbar.grid(row=1, column=0, sticky=tk.EW)

canvas = tk.Canvas(root, yscrollcommand=yscrollbar.set,
	xscrollcommand=xscrollbar.set)

canvas.grid(row=0, column=0, sticky=tk.NSEW)

yscrollbar.config(command=canvas.yview)
xscrollbar.config(command=canvas.xview)

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

frame = tk.Frame(canvas)
frame.rowconfigure(1, weight=1)
frame.columnconfigure(1, weight=1)

rows = 20
for i in range(0,rows):
	frame.columnconfigure(i, weight=1)
	for j in range(0,9):
		button = tk.Button(frame, padx=8, pady=8, text="[%d,%d]" % (i,j))
		if i < 3:
			frame.columnconfigure(i, weight=3)
			button.grid(row=i, columnspan=3, sticky=tk.W)
			button.config(width=15)
			if j == 3:
				break
		elif i >= 3 and i < 5:
			frame.columnconfigure(i, weight=5)
			button.grid(row=i, columnspan=5, sticky=tk.W)
			button.config(width=10)
			if j == 5:
				break
		else:
			button.grid(row=i, column=j, sticky=tk.W)
			button.config(width=40)

canvas.create_window(0, 0, anchor=tk.NW, window=frame)

frame.update_idletasks()

canvas.config(scrollregion=canvas.bbox("all"))

root.mainloop()

Re: Hilfe zu columnconfigure und columnspan

Verfasst: Donnerstag 30. Juni 2022, 12:31
von peterpy
Hallo Nobuddy,

ich versteh nicht was Du willst:
laut deinem Code sollen in den Zeilen 0 bis 2 je neun Tasten in einer Zeile angeordnet werden?
Laut deinem Beschrieb aber nur vier. Du Iterierst aber über neun Spalten(j), erzeugst also 9 Tasten.
Da Du column nicht angegeben hast, werden alle in Spalte Null plaziert.
Was willst Du mit dem weight? Die bezeichnet den Faktor zum dehnen.
Mit columnspan erstreckt sich dein Widget über die angegebene Anzahl Spalten, beginnend mit column=j
Du willst deine Tasten über 4, 6 und 8 Spalten verteilen. Also benötigst Du 24 Spalten.
In den ersten drei Zeilen erstreckt sich eine Taste über 24 / 4 = sechs Spalten
In den Zeile drei bis fünf erstrecken sich die Tasten über vier Spalten und der Rest über drei Spalten.
Um die Tastenbreite gleich zu halten, gibst Du sticky=tk.E+tk.W an.
Gruss Peter

Re: Hilfe zu columnconfigure und columnspan

Verfasst: Donnerstag 30. Juni 2022, 12:36
von Sirius3
Dein Code stimmt nicht mit der Erklärung oben überein.
Dass man mit 4 Leerzeichen pro Ebene einrückt, und nicht mit Tabs oder 2 Leerzeichen, wurde Dir hier schon öfter geschrieben. tk.call ist hier überflüssig (hab ich Dir auch schon geschrieben).
Die vielen if-Abfragen machen es sehr schwierig, überhaupt zu verstehen, wann was passiert.

Code: Alles auswählen

import tkinter as tk


def create_button_row(frame, row, count, span):
    for j in range(count):
        button = tk.Button(frame, padx=8, pady=8, text="[%d,%d]" % (row, j), width=5*span)
        button.grid(row=row, column=j*span, columnspan=span, sticky=tk.EW)


def main():
    frame = tk.Tk()

    for row in range(0, 3):
        create_button_row(frame, row, count=3, span=3)
    for row in range(3, 5):
        create_button_row(frame, row, count=6, span=2)
    for row in range(5, 20):
        create_button_row(frame, row, count=9, span=8)
                
    frame.mainloop()

if __name__ == "__main__":
    main()

Re: Hilfe zu columnconfigure und columnspan

Verfasst: Donnerstag 30. Juni 2022, 12:46
von peterpy
@sirius, ich denke Nobuddy wollte das so:

Code: Alles auswählen

import tkinter as tk


def create_button_row(frame, row, count, span):
    for j in range(count):
        button = tk.Button(frame, padx=8, pady=8, text="[%d,%d]" % (row, j), width=5*span)
        button.grid(row=row, column=j*span, columnspan=span, sticky=tk.EW)


def main():
    frame = tk.Tk()

    for row in range(0, 3):
        create_button_row(frame, row, count=3, span=8)
    for row in range(3, 5):
        create_button_row(frame, row, count=4, span=6)
    for row in range(5, 24):
        create_button_row(frame, row, count=8, span=3)
                
    frame.mainloop()

if __name__ == "__main__":
    main()
Gruss Peter

Re: Hilfe zu columnconfigure und columnspan

Verfasst: Donnerstag 30. Juni 2022, 14:17
von Nobuddy
Hallo und Danke, für Eure Hilfe!

Der Code ist ja fast identisch, von Euch beiden.
Peter verwendet die Widgetbreite, was meiner Vorstellung entspricht.
Jedoch, wird nicht die Breite 10, 15, 40 verwendet.
Die Spalten der Reihen, sollen keine Abhängigkeit zu einander haben, daher auch die unterschiedlichen Breiten der Widgets.
Habe den Code mal entsprechend geändert, aber das Ergebnis entspricht immer noch nicht dem.

Code: Alles auswählen

import tkinter as tk


def create_button_row(frame, row, count, span, width):
    for j in range(count):
        button = tk.Button(frame, padx=8, pady=8, 
			text="[%d,%d]" % (row, j), width=width)
        button.grid(row=row, column=j*span, columnspan=span, sticky=tk.EW)


def main():
    frame = tk.Tk()

    for row in range(0, 3):
        create_button_row(frame, row, count=3, span=8, width=15)
    for row in range(3, 5):
        create_button_row(frame, row, count=4, span=6, width=10)
    for row in range(5, 24):
        create_button_row(frame, row, count=8, span=3, width=40)

    frame.mainloop()

if __name__ == "__main__":
    main()

Re: Hilfe zu columnconfigure und columnspan

Verfasst: Donnerstag 30. Juni 2022, 14:42
von peterpy
Hallo Nobuddy,

was willst Du?
8 Spalten und die Breite der Widgets ist 40 = 320 Zeichen
6 Spalten, die Breite der Widgets ist 10 = 60 Zeichen
4 Spalten, die Breite der Widgets ist 10 = 40 Zeichen

Wenn deine Tasten auf die Breite beschränkt werden sollen, sieht das irgendwie komisch aus.

Code: Alles auswählen

button.grid(row=row, column=j*span, columnspan=span)
Du musst dich entscheiden,, willst Du eine "pyramidenstumpf-förmige" Anordnung?
Dann brauchen die unterschiedlichen Spaltenvarianten je einen Frame.
Gruss Peter

Re: Hilfe zu columnconfigure und columnspan

Verfasst: Donnerstag 30. Juni 2022, 15:07
von Nobuddy
peterpy hat geschrieben: Donnerstag 30. Juni 2022, 14:42 Du musst dich entscheiden,, willst Du eine "pyramidenstumpf-förmige" Anordnung?
Dann brauchen die unterschiedlichen Spaltenvarianten je einen Frame.
Das ist es eine "pyramidenstumpf-förmige" Anordnung".
Dachte, dass das ohne weiteren Frame gehen würde, was wohl nicht der Fall ist.

Euer Code, war für mich aufschlussreich, kannte ich bisher so nicht.

Danke für Eure Hilfe :wink: