02-04-2019, 05:42 AM
Hola buenas, tengo una aplicacion que añade filas con widgets en una ventana y necesito que la barra de scroll se active automaticamente cuando supere el alto de la ventana pero no lo hace, sin embargo si maximizo la ventana de repente se activa. Este es el código que estoy usando:
Gracias de antemano, un saludo.
Código:
import tkinter as tk
from tkinter import ttk
from functools import partial
class VerticalScrolledFrame(tk.Frame):
def __init__(self, parent, *args, **kw):
super().__init__(parent, *args, **kw)
self._vscrollbar = tk.Scrollbar(self, orient=tk.VERTICAL)
self._vscrollbar.pack(fill=tk.Y, side=tk.RIGHT, expand=tk.FALSE)
self._canvas = tk.Canvas(self, bd=0, highlightthickness=0,
yscrollcommand=self._vscrollbar.set)
self._canvas.pack(side=tk.TOP, fill=tk.BOTH, expand=tk.TRUE)
self._vscrollbar.config(command=self._canvas.yview)
self._canvas.xview_moveto(0)
self._canvas.yview_moveto(0)
self._inner_frame = tk.Frame(self._canvas, bg='white')
self._inner_id = self._canvas.create_window(0, 0,
window=self._inner_frame,
anchor=tk.NW
)
self._inner_frame.bind("<MouseWheel>", self._on_mousewheel)
self._inner_frame.bind('<Configure>', self._configure_inner)
self._canvas.bind('<Configure>', self._configure_canvas)
@property
def container(self):
return self._inner_frame
def _configure_canvas(self, event):
width = max(self._inner_frame.winfo_reqwidth(),
self._canvas.winfo_width())
height = max(self._inner_frame.winfo_reqheight(),
self._canvas.winfo_height())
self._canvas.itemconfigure(self._inner_id, width=width, height=height)
def _configure_inner(self, event):
self._canvas.configure(scrollregion=self._canvas.bbox("all"))
def _on_mousewheel(self, event):
self._canvas.yview_scroll(int(-1 * (event.delta / 120)), "units")
return "break"
def addNewRow(self):
#Obtiene las filas que hay actualmente en pantalla
num_rules = len(self.list)
#Lista para guardar los ITEMS
items = []
#Lista para guardar los valores de los ITEMS
items_values = []
#Crea el checkbutton en cada fila
c = tk.Checkbutton(self.frame.container)
#Añade el checkbutton a la lista de items
items.append(c)
#Coloca el checkbutton
c.grid(row=num_rules+1, column=0)
for i in range(0, 6):
#Variable asociada al combobox
var_text = tk.StringVar()
#Crea el combobox para cada atributo
b = ttk.Combobox(self.frame.container, textvariable=var_text,
state="readonly", justify='center')
#Asocia el evento de scroll para que se pueda hacer scroll en el
#frame de las reglas
b.bind("<MouseWheel>", self.frame._on_mousewheel)
#Añade cada combobox a una lista
items.append(b)
#Añade las variables asociadas a esos combobox a otra lista
items_values.append(var_text)
#Coloca el combobox
b.grid(row=num_rules+1, column=i+1)
#Añade las listas de items y de valores de los items a las otras
#listas
self.list.append(items)
class Application(ttk.Frame):
def __init__(self, main_window):
super().__init__(main_window)
main_window.title("Example")
main_window.geometry("800x500")
self.frame = VerticalScrolledFrame(main_window)
self.frame.place(rely=0, relheight=0.9, relwidth=1)
self.list = []
button = tk.Button(main_window, text='ADD',
command=partial(addNewRow, self))
button.place(relwidth=1, relheight=0.1, rely=0.9)
main_window = tk.Tk()
app = Application(main_window)
app.mainloop()