ich habe nun meinen code vereinfacht zusammengefasst, aus dem mein problem deutlich wird.
das problem ist, daß ich es nicht richtig hinbekomme die höhe eines labels in einem canvas korrekt auszulesen,
und zwar so, daß das die Label-Höhe mit der Scrollhöhe zusammenpasst.
in diesem beispiel ist schon bei eingabe der zeile 5 das ende der Scrollhöhe erreicht, obwohl es insgesamt 15 zeilen gibt
Code: Alles auswählen
import tkinter as tk
val_list = [['Spalte_1', 'Spalte_2', 'Spalte_3', 'Spalte_4'],
['a', 'b', 'c', 'd'],
['e', 'f', 'g', 'h'],
['i', 'j', 'k', 'l'],
['m', 'n', 'o', 'p'],
['q', 'r', 's', 't'],
['u', 'v', 'w', 'x'],
['y', 'z', '', ''],
['aa', 'bb', 'cc', 'dd'],
['ee', 'ff', 'gg', 'hh'],
['ii', 'jj', 'kk', 'll'],
['mm', 'nn', 'oo', 'pp'],
['qq', 'rr', 'ss', 'tt'],
['uu', 'vv', 'ww', 'xx'],
['yy', 'zz', '', '']
]
root = tk.Tk()
root.geometry("300x350+500+200")
info_frame = tk.Frame(root)
info_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=False, padx=5)
preview_frame = tk.Frame(root)
preview_frame.pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True, padx=5)
preview_frame.columnconfigure(0, weight=1)
preview_frame.rowconfigure(0, weight=1)
canvas = tk.Canvas(preview_frame, bg="lightgrey", bd=1, highlightthickness=1)
canvas.grid(row=0, column=0, sticky=tk.NSEW, padx=1, pady=1)
vsbar = tk.Scrollbar(preview_frame, orient=tk.VERTICAL, command=canvas.yview)
vsbar.grid(row=0, column=1, sticky=tk.NS)
hsbar = tk.Scrollbar(preview_frame, orient=tk.HORIZONTAL, command=canvas.xview)
hsbar.grid(row=1, column=0, sticky=tk.EW)
canvas.configure(xscrollcommand=hsbar.set, yscrollcommand=vsbar.set)
label_frame = tk.Frame(canvas, bg="lightgrey")
user_input = tk.StringVar()
number_lst = []
label_lst = []
def main():
user_frame = tk.Frame(info_frame)
user_frame.grid(column=0, row=2, sticky=tk.NSEW, pady=10)
tk.Label(user_frame, text="Zeile:", justify=tk.LEFT, anchor=tk.W).grid(column=0, row=0, sticky=tk.NSEW, padx=2)
tk.Entry(user_frame, textvariable=user_input, width=25).grid(column=0, row=1, sticky=tk.NSEW, padx=2, pady=5)
tk.Button(user_frame, text="Losrömern", command=get_user_input).grid(column=0, row=2)
def set_table(values):
for val_idx in range(len(values)):
lb_cell = tk.Label(label_frame,
text=val_idx + 1,
width=3
)
lb_cell.grid(column=0, row=val_idx, sticky=tk.NSEW)
number_lst.append(lb_cell)
for i, cell_list in enumerate(values):
cell_lst = []
for j, cell_text in enumerate(cell_list):
lb_cell = tk.Label(label_frame,
text=cell_text,
relief=tk.GROOVE,
bg="white",
fg="black",
padx=10,
pady=5,
)
lb_cell.grid(column=j+1, row=i, sticky=tk.NSEW)
cell_lst.append(lb_cell)
label_lst.append(cell_lst)
canvas.create_window((0, 0), window=label_frame, anchor=tk.NW)
label_frame.update_idletasks()
bbox = canvas.bbox(tk.ALL)
canvas.configure(scrollregion=bbox,
width=preview_frame.winfo_width(),
height=preview_frame.winfo_height(),
xscrollcommand=hsbar.set,
yscrollcommand=vsbar.set
)
def _bound_to_mousewheel(_):
canvas.bind_all("<MouseWheel>", _on_mousewheel)
def _unbound_to_mousewheel(_):
canvas.unbind_all("<MouseWheel>")
def _on_mousewheel(event):
canvas.yview_scroll(int(-1 * (event.delta / 120)), "units")
canvas.bind('<Enter>', _bound_to_mousewheel)
canvas.bind('<Leave>', _unbound_to_mousewheel)
def get_user_input():
if user_input.get().isdigit():
# 'target_label' symbolisiert die Zeilenhöhe (durchnummeriert ganz links in der Tabelle).
# Zu diesem Label soll immer hingescrollt werden.
target_label = number_lst[int(user_input.get())-1]
print("Zeile:", int(user_input.get()), "Name Ziel-Label:", target_label)
# y-Koordinate
label_y = canvas.canvasy(number_lst[int(user_input.get())-1].winfo_y()) # WAHRSCHEINLICH FALSCH ? :(
print(label_y)
# Höhe des Canvas
x1, y1, x2, y2 = canvas.bbox(tk.ALL)
canvas_height = y2-y1
print(canvas_height)
# y-Koordinate geteilt durch Höhe des Canvas
scroll_value = float(label_y / canvas_height)
canvas.yview_moveto(scroll_value)
else:
print("Bitte 'ne ganze Zahl")
print('---')
main()
set_table(val_list)
root.mainloop()