【问题标题】:How do you keep a widget in view while scrolling?滚动时如何保持小部件可见?
【发布时间】:2016-07-09 03:10:35
【问题描述】:

我正在使用 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 调整大小。另一个缺点是水平滚动条只相对于frame1。

  • 找到滚动条的中点并使用位置更新按钮相对于这些坐标的位置(也许?)不确定如何实现这一点,并且看到一般的 SO 解决方案我认为这可能是一种低效的方法这样做。

编辑:虽然这不是我的想法,但以下代码按照 cmets 中的 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()

【问题讨论】:

  • 把按钮从 ScrolledWindow 中拿出来怎么样?
  • @falsetru 一旦您知道解决方案的简单程度,我总是感到惊讶。你想做出一个正式的回答让我接受吗?我将在问题或其他内容中编辑工作代码。在解决方案 1 没有成功后,我避开了这条路线。谢谢!

标签: python python-2.7 tkinter tix


【解决方案1】:

你可以把按钮移出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()

【讨论】:

    【解决方案2】:

    您提到的第二个选项可能是满足您情况的选项,但是计算量很大,因为您需要删除按钮并相对于滚动条向上/向下运动一遍又一遍地重绘它们。这不仅在设计上很丑陋,而且如果您的应用程序运行一些严重的操作,它可能会成为您的应用程序进一步扩展的障碍,甚至会导致意外的错误。

    对于您的问题,我看到的唯一现实的解决方案是修复上部画布(或您要设置的任何区域)上(例如底部)和可滚动区域之外的按钮,正如@falsetru 评论的那样.

    【讨论】:

    • 它在美学上仍然不如在窗口中滚动并看到固定位置的东西那么令人愉悦,但它确实可以完成工作。我会等待 falsetru 发布答案。
    猜你喜欢
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 2018-12-06
    • 2018-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多