将Tkinter滚动条跳转到某个小部件

时间:2020-01-19 13:21:17

标签: python tkinter

我已经在Tkinter GUI中添加了一些滚动条功能

self.canvas = tk.Canvas(self.baseframe)
self.scrollbar = tk.Scrollbar(self.baseframe, orient="vertical", command=self.canvas.yview)
self.scrollable = tk.Frame(self.canvas)
self.scrollable.bind("<Configure>", lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all")))
self.canvas.create_window((0, 0), window=self.scrollable, anchor="n")
self.canvas.configure(yscrollcommand=self.scrollbar.set)
self.canvas.bind_all("<MouseWheel>", self._mousescroll)

我将_mousecroll()定义为

    def _mousescroll(self, event):
        """mouse wheel scroll callback"""
        # Divide the event.delta by some value to effect the scrolling speed
        self.canvas.yview_scroll(int(-1*(event.delta/120)), "units")

效果很好。

然后我将一些tkLabelFrame小部件添加到滚动区域(它们本身包含显示内容的小部件-与该问题无关)。整个滚动功能效果很好。

在我的GUI的另一部分中,我希望用户能够通过单击按钮来“跳转”到滚动区域中的特定点。实际上,将滚动区域自动滚动到此点。这可能吗?我对GUI代码具有完全控制权,因此我可以将标签添加到tkLabelFrames列表中,将其存储在某种列表/词典中,以便可以轻松地查找它们……诸如此类?

注意:添加到滚动区域中的tkLabelFrames的数量是动态的,因此某种绝对的“跳转到这么多像素”可能不起作用。我希望可能会有某种“滚动到带有此标签/属性等的小部件”功能。任何帮助表示赞赏。谢谢。

1 个答案:

答案 0 :(得分:1)

我之所以如此,是因为它在Google中的第一个结果而不是每个人的小部件的高度都是相同的(根据当前接受的答案的解决方案要求)。


使用一些.winfo函数,我们可以进行一些快速数学运算,以找到要跳转到“ self.scrollable”中确切位置的小部件。

注意::在调用Jump函数之前,可能需要在tkinter实例上调用.update(),否则Winfo值可能不正确。


我们将使用以下内容:

  • .winfo_height()-获取此小部件的高度,以像素为单位。如果窗口不是由几何管理器管理的,则将返回1。

  • .winfo_rooty()-获取窗口小部件上边缘相对于屏幕左上角的像素坐标。

  • .yview_moveto(fraction)-将视图移动到位置。 0是顶部,1是底部


以下功能将跳至给定的小部件,将其放在可见区域(self.canvas)的顶部。

 def jump_to_widget_top(self, widget):
      if self.scrollable.winfo_height() > self.canvas.winfo_height():
           pos = widget.winfo_rooty() - self.scrollable.winfo_rooty()
           height = self.scrollable.winfo_height()
           self.canvas.yview_moveto(pos / height)

首先,我们检查容器(self.scrollable)实际上是否大于查看区域。如果一切都已显示,则无需跳转。

我们找到所需窗口小部件的绝对位置(相对于屏幕),然后减去从容器顶部(可滚动)到屏幕顶部的距离。这使我们可以将小部件的位置相对于容器的位置。

找到窗口小部件的位置后,将其除以容器的高度(可自滚动),即可得到.yview_moveto()所需的窗口小部件的小数位。