Python Tkinter中的滚动条

Python Tkinter中的滚动条,python,tkinter,Python,Tkinter,我尝试了很多方法来做两件事: 将我的内容居中(水平) 有一个左右滚动条 这是我的代码: #编码:utf8 从tkinter进口* 从tkinter导入ttk class Program: def __init__(self): # Tk.__init__(self) # Fill the content of the window self.window = Tk() self.window.geometry(&quo

我尝试了很多方法来做两件事:

  • 将我的内容居中(水平)
  • 有一个左右滚动条
这是我的代码: #编码:utf8 从tkinter进口* 从tkinter导入ttk

class Program:

    def __init__(self):
        # Tk.__init__(self)
        # Fill the content of the window
        self.window = Tk()
        self.window.geometry("1080x720")

        self.createFrameWithScrollbar()
        self.content()

    def createFrameWithScrollbar(self):
        # Create a Main Frame
        self.mainFrame = Frame(self.window)
        self.mainFrame.pack(fill=BOTH, expand=True)
        # Create a canvas
        self.canvas = Canvas(self.mainFrame)
        self.canvas.pack(side=LEFT, fill=BOTH, expand=True)
        # Add a scrobar
        yScrollbar = ttk.Scrollbar(self.mainFrame, orient=VERTICAL, command=self.canvas.yview)
        yScrollbar.pack(side=RIGHT, fill=Y)
        xScrollbar = ttk.Scrollbar(self.mainFrame, orient=HORIZONTAL, command=self.canvas.xview)
        xScrollbar.pack(side=BOTTOM, fill=X)
        # Configure the canvas
        self.canvas.configure(yscrollcommand=yScrollbar.set)
        self.canvas.configure(xscrollcommand=xScrollbar.set)
        self.canvas.bind('<Configure>', lambda e: self.canvas.configure(scrollregion = self.canvas.bbox("all")))

        self.frame = Frame(self.canvas)
        self.canvas.create_window((0,0), window=self.frame, anchor="nw")

        self.currentFrame = Frame(self.frame)
        self.currentFrame.configure(bg="red")
        self.currentFrame.pack(fill=BOTH, expand=1)

    def content(self):
        label_title = Label(self.currentFrame, text="Title")
        label_title.grid(column=0, row=0, sticky=NSEW)
        label_description = Label(self.currentFrame, text="Title")
        label_description.grid(column=0, row=1, sticky=NSEW)
        label_version = Label(self.currentFrame, text="0.2 beta [Novembre 2020]")
        label_version.grid(column=0, row=2, sticky=NSEW)


# Lauch the program
app = Program()
app.window.mainloop()
class程序:
定义初始化(自):
#Tk.\uuuuuu初始(自我)
#填充窗口的内容
self.window=Tk()
自窗口几何(“1080x720”)
self.createFrameWithScrollbar()
self.content()
def createFrameWithScrollbar(自身):
#创建一个主框架
self.mainFrame=Frame(self.window)
self.mainFrame.pack(fill=BOTH,expand=True)
#创建画布
self.canvas=canvas(self.mainFrame)
self.canvas.pack(side=LEFT,fill=BOTH,expand=True)
#添加一个工具栏
yScrollbar=ttk.Scrollbar(self.mainFrame,orient=VERTICAL,command=self.canvas.yview)
yScrollbar.pack(侧面=右侧,填充=Y)
xScrollbar=ttk.Scrollbar(self.mainFrame,orient=HORIZONTAL,command=self.canvas.xview)
xScrollbar.pack(侧面=底部,填充=X)
#配置画布
self.canvas.configure(yscrollcommand=yScrollbar.set)
configure(xscrollcommand=xScrollbar.set)
self.canvas.bind(“”,lambda e:self.canvas.configure(scrollregion=self.canvas.bbox(“全部”))
self.frame=frame(self.canvas)
self.canvas.create_window((0,0),window=self.frame,anchor=“nw”)
self.currentFrame=Frame(self.Frame)
self.currentFrame.configure(bg=“红色”)
self.currentFrame.pack(fill=BOTH,expand=1)
def内容(自我):
标签\标题=标签(self.currentFrame,text=“title”)
label_title.grid(列=0,行=0,粘性=NSEW)
标签\描述=标签(self.currentFrame,text=“Title”)
label_description.grid(列=0,行=1,粘性=NSEW)
label\u version=label(self.currentFrame,text=“0.2 beta[Novenbre 2020]”)
label_version.grid(列=0,行=2,粘性=NSEW)
#启动程序
app=程序()
app.window.mainloop()
因此,结果如下:

有什么建议吗

底部边栏太小了!我不知道为什么。 关于文本,它根本不是中心;( 如果我重新调整窗口,我想让它居中并改变位置


非常感谢

pack
通过沿主控形状的整个空侧分配空间来工作,因此调用pack的顺序很重要。在打包滚动条之前打包画布时,画布从上到下占据整个左侧

简单的解决方案是在打包画布之前打包滚动条

yScrollbar.pack(side=RIGHT, fill=Y)
xScrollbar.pack(side=BOTTOM, fill=X)
self.canvas.pack(side=LEFT, fill=BOTH, expand=True)
为了让UI看起来更专业一点,在布置滚动条时,
grid
通常是一个更好的选择。使用
pack
,水平滚动条的一个边缘将位于垂直滚动条的下方,或者垂直滚动条的边缘将直接位于水平滚动条的旁边。或者,您必须添加一点填充以使滚动条看起来不重叠

当我有一个可滚动的小部件时,我几乎总是使用
grid
将它和一个或两个滚动条放在一个框架中。然后,在将它们添加到UI的其余部分时,我可以将它们视为一个小部件


在评论中,您询问如何在网格中执行此操作。您只需将小部件放置在适当的行和列中,并确保带有可滚动小部件的行和列具有非零权重,以便为其分配任何额外空间

self.mainFrame.grid_rowconfigure(0, weight=1)
self.mainFrame.grid_columnconfigure(0, weight=1)

yScrollbar.grid(row=0, column=1, sticky="ns")
xScrollbar.grid(row=1, column=0, sticky="ew")
self.canvas.grid(row=0, column=0, sticky="nsew")

您应该在两个滚动条之后打包画布。目前,它占据了包含框架的整个左侧,因此其他所有内容都必须完全位于其右侧。此外,建议使用all
pack
或all
grid
并不要混合几何体管理器……除非您是受虐狂。@jasonharper例如我试过了,但什么也没有changed@AndrewAllaire:谢谢你的建议。我正在发现Tkinter,所以让我们尝试使用grid。不确定是否能够找到相同的thing@AndrewAllaire:我几乎总是在应用程序中同时使用
pack
grid
。它们各有优缺点。如果你不这样做,我认为你更像是受虐狂我想用一个就可以做任何事情。谢谢!你知道如何用网格做同样的事情吗?我已经试过了,但还没有定论,所以按照你给我的解决方案,两个滚动条都是可以的;)只是我的问题仍然是将content@f42:
grid
pack
一样简单。只要阅读一下
网格
的文档,它就有你需要知道的一切。我试过了,但没有成功。画布中的最后一帧不占用所有空间。其他的是OK@f42:无需设置minsize即可使其工作。