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