Tkinter 小部件上的垂直和水平滚动条 [英] Vertical and Horizontal Scrollbars on Tkinter Widget

查看:74
本文介绍了Tkinter 小部件上的垂直和水平滚动条的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将数据库的内容输出到 Tkinter 小部件.数据库有足够的行和列,我需要同时启用水平和垂直滚动条,但我很难让水平和垂直滚动同时工作.我不知道使用哪个 Tkinter 小部件,但这是我当前的实现:

I am trying to output the contents of a database to a Tkinter widget. The database has enough rows and columns to where I need to have both horizontal and vertical scrollbars enabled, but I am having a hard time getting horizontal and vertical scrolling to work simultaneously. I am agnostic about which Tkinter widget is used but here is my current implementation:

# Create root
self.root = Tk()
self.root.geometry('1000x500+0+0')

# Create canvas
self.canvas = Canvas(self.root)
self.canvas.pack(side=TOP, fill=BOTH, expand=TRUE)

# Create scrollbars
self.xscrollbar = Scrollbar(self.root, orient=HORIZONTAL, command=self.canvas.xview)
self.xscrollbar.pack(side=BOTTOM, fill=X)
self.yscrollbar = Scrollbar(self.root, orient=VERTICAL, command=self.canvas.yview)
self.yscrollbar.pack(side=RIGHT, fill=Y)

# Attach canvas to scrollbars
self.canvas.configure(xscrollcommand=self.xscrollbar.set)
self.canvas.configure(yscrollcommand=self.yscrollbar.set)

# Create frame inside canvas
self.frame = Frame(self.canvas)
self.canvas.create_window((0,0), window=self.frame, anchor=NW)
self.frame.bind('<Configure>', self.set_scrollregion)

# Write db contents to canvas
self.print_dbcontents()

# Invoke main loop
self.root.mainloop()

def set_scrollregion(self, event):
    self.canvas.configure(scrollregion=self.canvas.bbox('all'))

在这个实现中,我只能滚动到一个方向,这取决于我如何打包画布:

In this implementation, I can only get scrolling to work in one direction, depending on how I pack the canvas:

self.canvas.pack(side=TOP, fill=BOTH, expand=TRUE) # scrolling works in x but not y
self.canvas.pack(side=LEFT, fill=BOTH, expand=TRUE) # scrolling works in y but not x

我只需要让水平和垂直滚动同时工作,或者找到替代解决方案.

I just need to get horizontal and vertical scrolling to work simultaneously, or find an alternate solution.

推荐答案

我没有看到任何会阻止滚动条工作的代码.我确实看到了一个问题,它阻止了其中一个滚动条出现在您期望的位置(假设您希望它们出现在传统位置).当您说您希望他们同时工作"时,这就是您的意思吗?

I don't see any code that would prevent the scrollbars from working. I do see a problem that prevents one of the scrollbars from showing up where you expect it (assuming you expect them to appear in the traditional place). Is that what you mean when you say you want them to "work simultaneously"?

您的布局使用以下代码并按以下顺序完成:

Your layout is done with the following code and in the following order:

self.canvas.pack(side=TOP, fill=BOTH, expand=TRUE)
self.xscrollbar.pack(side=BOTTOM, fill=X)
self.yscrollbar.pack(side=RIGHT, fill=Y)

第一行使画布填满小部件的整个顶部,从左侧一直到右侧.当您稍后将 yscrollbar 放在右侧时,这意味着在画布填满顶部后,它会移到 左侧空间的右侧.由于画布填满了顶部,因此右侧没有剩余空间,只有下方.因此,您的滚动条将显示为一个关于画布下方水平滚动条高度的小部件.

That first line causes the canvas to fill the whole top of the widget, all the way from the left to all the way to the right. When you later place the yscrollbar on the right, this means it goes to the right of the space left over after the canvas fills up the top. Since the canvas fills the top, there is no left over space to the right, only below. Thus, your scrollbar will appear as a tiny widget about the height of the horizontal scrollbar below the canvas.

一个快速的解决方法是先打包垂直滚动条,然后是水平滚动条,然后是画布.然后.您的主要"小部件应该始终是您打包/网格的最后一件事.一,您这样做的原因很明显,在这种情况下您需要获得所需的效果,而且还因为它使您的调整大小行为正确.我正在偏离主题来解释这个答案中的原因,因此请阅读 stackoverflow 上的这个答案 了解更多信息.

A quick fix is to pack the vertical scrollbar first, then the horizontal, and then the canvas. Your "major" widget should always be one of the last things you pack/grid. One, you do that for the obvious reason that you need to in this case to get the desired effect, but also because it makes your resize behavior right. I'm getting off topic to explain why in this answer, so read this answer on stackoverflow for more information.

第二,在使用滚动条时,如果您想要专业的外观,最好使用网格.如果您使用 pack,滚动条将不会在它们相遇的角落对齐属性.您希望它们看起来像这样,右下角有一个小的空白区域:

Second, when working with scrollbars it's best to use grid if you want a professional appearance. If you use pack, the scrollbars will not align property in the corner in which they meet. You want them to look like this, with a small blank space in the lower-right corner:

  ||
==

但是,如果您使用 pack,它们将如下所示:

However, if you use pack they'll look like one of these:

   ||    -or-      ||
 ====            ==||

最后,我鼓励您不要 import *,这可能会导致问题.相反,养成import Tkinter as tk 的习惯,然后在所有 tk 命令前加上tk".(例如:tk.Canvas 等).当您第一次尝试在同一个 UI 中混合使用 ttk 和 tkinter 小部件时,您会明白为什么这很重要,但是如果您也从其他包中导入 *",您可能会在其他地方遇到问题.另外,当您使用 tk 功能和使用其他包的功能时,这种方式很明显.

Finally, I encourage you to not import *, it could cause problems down the road. Instead, get in the habit of doing import Tkinter as tk and then prefixing all of the tk commands with "tk." (eg: tk.Canvas, etc). You'll see why this matters the first time you try to mix ttk and tkinter widgets in the same UI, but you could have problems elsewhere if you also "import *" from other packages as well. Plus, this way it's obvious when you're using tk features and when you're using features from other packages.

这篇关于Tkinter 小部件上的垂直和水平滚动条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆