Python Tkinter:在画布中添加滚动条到框架

时间:2016-02-24 08:10:35

标签: python canvas tkinter scrollbar tkinter-canvas

我对Tkinter很新,但是,我被要求创造"创造"一个简单的表单,用户可以提供有关其工作状态的信息(这是我常用工作的一个副项目)。 因为我需要有相当多的文本小部件(用户需要提供有关文档状态的评论,或者到目前为止开放的问题),我想要一些"可滚动的" (沿y轴)。

我浏览周围寻找解决方案,经过一些试验和错误,我发现了一些非常好的东西。 基本上我创建一个画布,并在画布内有一个滚动条和一个框架。在框架内,我有我需要的所有小部件。

这是代码的snipet(只有一些实际的小部件,特别是文本的小部件):

from Tkinter import *
## My frame for form
class simpleform_ap(Tk):
    # constructor
    def __init__(self,parent):
        Tk.__init__(self,parent)
        self.parent = parent
        self.initialize()
    #
    def initialize(self):
    #
        self.grid_columnconfigure(0,weight=1)
        self.grid_rowconfigure(0,weight=1)
        #
        self.canvas=Canvas(self.parent)
        self.canvas.grid(row=0,column=0,sticky='nsew')
        #
        self.yscrollbar = Scrollbar(self,orient=VERTICAL)
        self.yscrollbar.grid(column =4, sticky="ns")
        #
        self.yscrollbar.config(command=self.canvas.yview)
        self.yscrollbar.pack(size=RIGTH,expand=FALSE)
        #
        self.canvas.config(yscrollcommand=self.yscrollbar.set)
        self.canvas.pack(side=LEFT,expand=TRUE,fill=BOTH)
        #
        self.frame1 = Frame(self.canvas)
        self.canvas.create_window(0,0,window=self.frame1,anchor='nw')
        # Various Widget        
        # Block Part
        # Label
        self.labelVariableIP = StringVar()  # Label variable
        labelIP=Label(self.frame1,textvariable=self.labelVariableIP,
                     anchor="w",
                     fg="Black")
        labelIP.grid(column=0,row=0,columnspan=1,sticky='EW')
        self.labelVariableIP.set(u"IP: ")
        # Entry: Single line of text!!!!
        self.entryVariableIP =StringVar()  # variable for entry field
        self.entryIP =Entry(self.frame1,
                            textvariable=self.entryVariableIP,bg="White")
        self.entryIP.grid(column = 1, row= 0, sticky='EW')
        self.entryVariableIP.set(u"IP")
        # Update Button or Enter
        button1=Button(self.frame1, text=u"Update",
                       command=self.OnButtonClickIP)
        button1.grid(column=2, row=0)
        self.entryIP.bind("<Return>", self.OnPressEnterIP)
        #...
        # Other widget here
        #
        # Some Text
        # Label
        self.labelVariableText = StringVar()  # Label variable                
        labelText=Label(self.frame1,textvariable=
                        self.labelVariableText,
                 anchor="nw",
                 fg="Black")
    labelText.grid(column=0,row=curr_row,columnspan=1,sticky='EW')
    self.labelVariableTexta.set(u"Insert some texts: ")
    # Text
    textState = TRUE
    self.TextVar=StringVar()
    self.mytext=Text(self.frame1,state=textState,
                     height = text_height, width = 10,
                     fg="black",bg="white") 
    #
    self.mytext.grid(column=1, row=curr_row+4, columnspan=2, sticky='EW')
    self.mytext.insert('1.0',"Insert your text")
    #
    # other text widget here
    #
    self.update()
    self.geometry(self.geometry() )
    self.frame1.update_idletasks()
    self.canvas.config(scrollregion=(0,0,
                       self.frame1.winfo_width(),
                       self.frame1.winfo_height()))
#
def release_block(argv):

    # Create Form
    form = simpleform_ap(None)
    form.title('Release Information')
    #
    form.mainloop()
#

if __name__ == "__main__":
  release_block(sys.argv)

正如我之前提到的,这个脚本完全可以完成这项工作,即使它有一些小问题不是&#34;基础&#34;但有点烦人。

当我启动它时,我得到了这个(抱歉屏幕捕获不好): enter image description here

可以看出,它只显示第一个&#34;列&#34;网格,虽然我想拥有它们(在我的情况下,它们应该是4) 要查看所有字段,我必须手动(使用鼠标)窗口调整大小。 我想拥有的是这样的(所有4列都在那里): enter image description here

此外,滚动条不会在整个窗体上延伸,但它只是在窗口的右下角。

虽然后一个问题(滚动条)我可以随身携带,但第一个问题更重要一点,因为我希望让最终用户拥有一个&#34;图片&#34;他们应该做什么而不需要调整窗户大小。

有没有人知道我应该如何处理? 我错过了什么?

提前感谢您的帮助

1 个答案:

答案 0 :(得分:3)

在班级的__init__方法中,您似乎没有设置主窗口的大小。你应该这样做,或者它只是将窗口设置为默认大小,它只显示它可以的任何东西,在你的情况下,只有1列。因此,在__init__方法中,尝试将self.geometry(str(your_width) + "x" + str(your_height))放在your_widthyour_height所在的任何整数中,以便您在窗口中查看所需内容。

至于滚动条问题,我所要做的就是将滚动条添加到画布的方式更改为.pack(),并将属性fill = 'y' and side = RIGHT添加到其中,如下所示:

self.yscrollbar.pack(side = 'right', fill = 'y') 

另外,您不需要:

self.yscrollbar.config(command=self.canvas.yview)
self.yscrollbar.pack(size=RIGHT,expand=FALSE)

只需将命令选项添加到滚动条的创建中,如下所示:

self.scrollbar = Scrollbar(self,orient=VERTICAL,command=self.canvas.yview)

总之,以下更改应使您的代码按预期工作:

  • 添加:

    def __init__(self,parent):
        Tk.__init__(self,parent)
        self.parent = parent
        self.initialize()
        # Resize the window from the default size to make your widgets fit. Experiment to see what is best for you.
        your_width = # An integer of your choosing
        your_height = # An integer of your choosing
        self.geometry(str(your_width) + "x" + str(your_height))
    
  • 添加和编辑:

    # Add `command=self.canvas.yview`
    self.yscrollbar = Scrollbar(self,orient=VERTICAL,command=self.canvas.yview)
    # Use `.pack` instead of `.grid`
    self.yscrollbar.pack(side = 'right', fill = 'y')
    
  • 卸下:

    self.yscrollbar.config(command=self.canvas.yview)
    self.yscrollbar.pack(size=RIGHT,expand=FALSE)