Grid-Manager-Problem
Verfasst: Montag 9. März 2020, 13:20
Hallo Freunde,
in meinem Code versuche ich Buttons in ein Frame in Canvas mit h-Scrollbar zu setzen.
Die Scrollbar wird eingeblendet, nur wenn sie gebraucht wird.
Das Ergebnis sieht so aus:

Die Scrollbar reagiert richtig (wird auch richtig ein- oder ausgeblendet).
Allerdings soll die Scrollbar direkt unter den Buttons sein.
Kann mir da vielleicht jmd helfen?
LG Christian
in meinem Code versuche ich Buttons in ein Frame in Canvas mit h-Scrollbar zu setzen.
Die Scrollbar wird eingeblendet, nur wenn sie gebraucht wird.
Code: Alles auswählen
import os
import sys
import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
class Selectionbar(tk.Frame):
def __init__(self, selections_frame, preview_table):
tk.Frame.__init__(self, selections_frame)
self.preview_table = preview_table
select = tk.Frame(selections_frame, bg='gainsboro')
select.pack(side=tk.TOP, fill=tk.BOTH, expand=True, padx=4, pady=4)
self.btn_option = tk.StringVar()
self.btn_option.set('Datenparameter')
auswahl_frame = tk.Frame(select, bg='gainsboro')
auswahl_frame.pack(side=tk.LEFT)
auswahl_frm = tk.Frame(auswahl_frame, bg='grey')
auswahl_frm.pack(fill=tk.BOTH, expand=False, padx=8)
self.t_btn = tk.Button(auswahl_frm,
text=self.btn_option.get(),
font=('Arial', 9, 'bold', 'italic'),
bg='lightsteelblue',
width=15,
command=self.btn_toggle
)
self.t_btn.pack(side=tk.LEFT, padx=8, pady=8)
################################################
# hier stimmt was nicht
self.button_frm = tk.Frame(select)
self.button_frm.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=4, pady=4) # <----
self.frames = {}
for F in (Datenparameter, Datenbeziehung):
page_name = F.__name__
frame = F(parent=self.button_frm, controller=self)
self.frames[page_name] = frame
frame.grid(row=0, column=0, sticky=tk.NSEW, padx=2, pady=2) # <---- frame wird an Datenparameter übergeben
################################################
self.show_frame("Datenparameter")
def btn_toggle(self):
if self.btn_option.get() == 'Datenparameter':
self.btn_option.set('Datenbeziehung')
self.t_btn['text'] = self.btn_option.get()
# Go to Frame 'Datenbeziehung'
self.show_frame("Datenbeziehung")
else:
self.btn_option.set('Datenparameter')
self.t_btn['text'] = self.btn_option.get()
# Go to Frame 'Datenparameter'
self.show_frame("Datenparameter")
def show_frame(self, page_name):
frame = self.frames[page_name]
frame.tkraise()
class Datenparameter(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.parent = parent # parent ist das übergebene frame von class Selectionbar
# controller ist die class Selectionbar
self.controller = controller
image_folder = os.path.join(os.getcwd(), "images")
btn_dict = controller.mapping_dict['Datenparameter']
spalten_key = list(btn_dict.keys())[0]
spalten_values = btn_dict[spalten_key]
self.configure(highlightbackground="lightsteelblue", highlightcolor="lightsteelblue", highlightthickness=1)
self.canvaser = tk.Canvas(self, bg="grey", bd=1, highlightthickness=1)
self.canvaser.grid(row=0, column=0, sticky=tk.NSEW, padx=1, pady=1)
self.hsbar = ttk.Scrollbar(self, orient=tk.HORIZONTAL, command=self.canvaser.xview)
self.hsbar.grid(row=1, column=0, sticky=tk.EW)
self.canvaser.configure(xscrollcommand=self.hsbar.set)
self.spalten_buttons = tk.Frame(self.canvaser, bg="grey")
for button_text, button_value in spalten_values.items():
img_info = Image.open(self.resource_LAYOUT(os.path.join(image_folder, button_value[1]))).resize((15, 15))
image_info = ImageTk.PhotoImage(img_info)
button = tk.Button(self.spalten_buttons,
image=image_info,
text=button_text,
font=('Consolas', 8),
compound=tk.LEFT)
button.image = image_info
button.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=4, pady=4) # Volle Breite nutzen: expand=True
self.canvaser.create_window((0, 0), window=self.spalten_buttons, anchor=tk.NW)
self.spalten_buttons.update_idletasks()
self.bbox = self.canvaser.bbox(tk.ALL)
self.canvaser.configure(scrollregion=self.bbox,
xscrollcommand=lambda mx_f, mx_l: self.auto_scroll(self.hsbar, mx_f, mx_l)
)
@staticmethod
def resource_LAYOUT(relative_path):
if hasattr(sys, '_MEIPASS'):
return os.path.join(os.environ.get("_MEIPASS", os.path.abspath(".")), relative_path)
return os.path.join(os.path.abspath("."), relative_path)
@staticmethod
def auto_scroll(sbar, first, last):
first, last = float(first), float(last)
if first <= 0 and last >= 1:
sbar.grid_remove()
else:
sbar.grid()
sbar.set(first, last)
class Datenbeziehung(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.configure(highlightbackground="lightsteelblue", highlightcolor="lightsteelblue", highlightthickness=1)

Die Scrollbar reagiert richtig (wird auch richtig ein- oder ausgeblendet).
Allerdings soll die Scrollbar direkt unter den Buttons sein.
Kann mir da vielleicht jmd helfen?
LG Christian