propiedades - tamaño de un label python
¿Cómo mantener un widget a la vista mientras se desplaza? (2)
Estoy usando Tix para crear automáticamente una barra de desplazamiento a medida que cambia el contenido. Quiero mantener un botón o dos en la vista del usuario mientras se desplazan por el contenido de la aplicación. Aún no he visto esta pregunta para Tkinter / Tix, así que pensé en preguntar.
El siguiente código creará una muestra del problema donde el botón se encuentra en un punto fijo de la ventana y está sujeto a desplazamiento.
from Tkinter import *
import Tix
class some_GUI:
def __init__(self, root):
sw= Tix.ScrolledWindow(root, scrollbar=Tix.AUTO)
sw.pack(fill=Tix.BOTH, expand=1)
frame1 = Frame(sw.window)
frame1.grid(row = 0, column = 1)
frame2 = Frame(sw.window)
frame2.grid(row = 0, column = 2)
def quit():
root.quit()
for i in range(0,300):
label1 = Label(frame1, text = "foo")
label1.grid(row = i, column = 0)
button = Button(frame2, text = "Quit", command = quit)
button.pack()
root = Tix.Tk()
display = some_GUI(root)
root.mainloop()
Quiero que los botones estén en "frame2" y que estén centrados verticalmente con respecto a la ventana de la aplicación. Intenté usar winfo_height / winfo_width para encontrar el alto / ancho del marco para trabajar con la actualización, pero estos valores no cambiaron con la adición de las etiquetas y el botón.
Soluciones probadas / posibles:
Puse frame2 en sw.subwidgets_all [1] haciendo lo siguiente:
frame1.pack(side = LEFT) frame2 = Frame(sw.subwidgets_all()[1]) frame2.pack(side = RIGHT) button = Button(frame2, text = "Quit", command = quit) button.pack(side = RIGHT)
Esto permite la posición fija en relación con la aplicación, pero la ventana cambia de tamaño en relación con el elemento primario del botón en lugar de frame1. Otro inconveniente es que la barra de desplazamiento horizontal es solo relativa a frame1.
Encontrar el punto medio de la barra de desplazamiento y actualizar la posición de los botones relativos a esas coordenadas utilizando el lugar (¿quizás?) No estoy seguro de cómo lograr esto, y ver las soluciones de SO en general, creo que esta podría ser una forma ineficiente de hacerlo.
EDITAR: aunque esto no es exactamente lo que tenía en mente, el siguiente código funciona según la sugerencia de falsetru en los comentarios:
from Tkinter import *
import Tix
class some_GUI:
def __init__(self, root):
def quit():
root.quit()
frame2 = Frame(root)
frame2.pack(side = RIGHT)
button = Button(frame2, text = "Quit", command = quit)
button.pack()
frame1 = Frame(root)
frame1.pack(side = LEFT)
sw= Tix.ScrolledWindow(frame1, scrollbar=Tix.AUTO)
sw.pack(fill=Tix.BOTH, expand=1)
for widget in sw.subwidgets_all():
print widget
for i in range(0,300):
label1 = Label(sw.window, text = "foo")
label1.grid(row = i, column = i)
print root.winfo_toplevel()
for widget in sw.subwidgets_all():
print widget
root = Tix.Tk()
display = some_GUI(root)
root.mainloop()
La segunda opción que mencionaste podría ser la que satisfaga tu situación, sin embargo, es computacionalmente costosa, ya que necesitarás eliminar los botones y volver a dibujarlos una y otra vez en relación con el movimiento de subida / bajada de la barra de desplazamiento. No solo esto es feo por diseño, sino que puede ser un obstáculo para cualquier escalabilidad adicional de su aplicación o incluso provocar errores inesperados si su aplicación ejecuta algunas operaciones serias.
La única solución realista que veo para su problema es fijar los botones en (por ejemplo, la parte inferior de) el lienzo superior (o cualquier región que desee establecer) y fuera de la región desplazable como lo comentó @falsetru.
Puedes poner el botón fuera de ScrollWindows:
import Tix
from Tkinter import *
def build_ui(root):
sw = Tix.ScrolledWindow(root, scrollbar=Tix.AUTO)
sw.pack(side=LEFT, fill=Tix.BOTH, expand=1)
for i in range(300):
label1 = Label(sw.window, text="foo")
label1.grid(row=i, column=0)
button = Button(root, text="Quit", command=root.quit)
button.pack(side=RIGHT)
root = Tix.Tk()
build_ui(root)
root.mainloop()