Как сохранить виджет во время прокрутки?

Я использую Tix для автоматического создания полосы прокрутки по мере изменения содержимого. Я хочу держать кнопку или два в представлении пользователя, пока они просматривают содержимое приложения. Я еще не видел этот вопрос для Tkinter / Tix, поэтому я думал, что спрошу.

Следующий код создаст образец проблемы, когда кнопка находится в фиксированной точке в окне и подвержена прокрутке.

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() 

Я хочу, чтобы кнопка (ы) находилась в «frame2» и центрирована по вертикали относительно окна приложения. Я попытался использовать winfo_height / winfo_width, чтобы найти высоту / ширину фрейма для работы с обновлением, но эти значения не изменились с добавлением меток и кнопки.

Попытки / возможные решения:

  • Я помещал frame2 в sw.subwidgets_all [1], выполняя следующие действия:

     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) 

    Это позволяет фиксированное положение относительно приложения, но окно изменяет размер относительно родителя кнопки, а не frame1. Другим недостатком является то, что горизонтальная полоса прокрутки находится только относительно кадра1.

  • Найдите среднюю точку полосы прокрутки и обновите положение кнопок относительно этих координат, используя место (возможно?), Не знаете, как это сделать, и, видя SO-решения в целом, я думаю, что это может быть неэффективным способом сделать это.

EDIT: Хотя это не совсем то, что я имел в виду, следующий код работает в соответствии с предложением falsetru в комментариях:

 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() 

Вы можете вывести кнопку из 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() 

Второй вариант, который вы упомянули, может быть тот, который удовлетворяет вашей ситуации, однако это дорого стоит вычислить, так как вам нужно будет удалить кнопку (кнопки) и перерисовать их снова и снова относительно движения вверх / вниз по полосе прокрутки. Это не только уродливо по дизайну, но и может стать препятствием для любой дополнительной масштабируемости вашего приложения или даже привести к неожиданным ошибкам, если ваше приложение выполняет некоторые серьезные операции.

Единственное реалистичное решение, которое я вижу для вашей проблемы, – это зафиксировать кнопку (ов) на (например, нижней части) верхнего холста (или любой другой регион, который вы хотите установить) и вне прокручиваемого региона, как прокомментировал @falsetru.