Tkinter网格中的滚动条 [英] Scrollbar in Tkinter grid

查看:144
本文介绍了Tkinter网格中的滚动条的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


可能存在重复:

在Tkinter的小部件网格中添加一个滚动条


在我的项目中,我希望使用Tkinter作为GUI在窗口中显示我的结果。我将它们放置在一个表格中,使用网格窗口小部件,并将窗口分成两个不同的部分(针对不同的结果)。但经过长时间运行后,显示的结果数量超过了我的屏幕高度,所以我想为我的程序添加一个滚动条。我已经在stackoverflow上看到了几个问题,最接近的答案是这样的:


(为了让你知道我在做什么)



虽然我不能将它应用到我的程序中,也许是因为我对Python很陌生,有时候认为我是一位Dr. Frankenstein,教程 - 例子。

现在我尝试了很多,但是我不能让表格显示在画布上,可能只是我缺少的一些小东西。



我创建了一个我的程序的抽象例子(没有滚动条),所以你知道我在做什么,也许你可以帮助我将它滚动到所属的位置!



非常感谢!

示例代码:(runs)

 将Tkinter导入为tk 
toprow = 1
botrow = 1
class ProgramWindow(tk.Frame):
$ b $ def __init __(self,name):
self.name = name
tk.Frame .__ init __( self,root)
self.pack()

if name ==BotWin:
tk.Label(self,text =FirstColBot,width = 30)。 grid(row = 0,column = 0)
tk.Label(self,text =SecndColBot,width = 20).grid(row = 0,column = 1)

elif name ==TopWin:
tk.Label(self,text =FirstColTop,width = 30).grid(row = 0,column = 0)
tk.Label SecndColTop,width = 20).grid(row = 0,column = 1)

def addrowTop(self,stuff,otherstuff):
全局toprow

textfield = tk.Text(self,width = 30,height = 1)
textfield.grid(row = toprow,column = 0)
textfield.insert('0.0',stuff)

textfield = tk.Text(self,width = 20,height = 1)
textfield.grid(row = toprow,column = 1)
textfield.insert('0.0',o

toprow + = 1

def addrowBot(self,stuff,otherstuff):
全局botrow

textfield = tk.Text (self,width = 30,height = 1)
textfield.grid(row = botrow,column = 0)
textfield.insert('0.0',stuff)

textfield = tk.Text(self,width = 20,height = 1)
textfield.grid(row = botrow,column = 1)
textfield.insert('0.0',otherstuff)

botrow + = 1

def SomeProg():
在范围内(20):
if i%2 == 0:
stuff =东西是+ str(i)
otherstuff = i * 3
Wins [0] .addrowTop(stuff,otherstuff)
elif i%2 == 1:
stuff = Stuff is+ str(i)
otherstuff = i * 4
Wins [1] .addrowBot(stuff,otherstuff)


root = tk.Tk ()
root.title(Stuff)

Wins = [ProgramWindow(TopWin),ProgramWindow(BotWin)]
SomeProg()

root.mainlo op()

其他代码会尝试添加滚动条(基于上面链接中显示的示例) 。
,如果滚动条只显示在下面部分,那可以,因为那是具有许多结果的部分。)

  import Tkinter as tk 
toprow = 1
botrow = 1
class ProgramWindow(tk.Frame):
$ b $ def __init __(self,name):
self.name = name
self.frame = tk.Frame .__ init __(self,root)


if name ==BotWin:
tk.Label(self,text =FirstColBot,width = 30).grid(row = 0,column = 0)
tk.Label(self,text =SecndColBot,width = 20) row = 0,column = 1)

self.canvas = tk.Canvas(root,borderwidth = 0,background =#ffffff)
self.vsb = tk.Scrollbar(root ,orient =vertical,command = self.canvas.yview)
self.canvas.configure(yscrollcommand = self.vsb.set)

self.vsb.pack(side =右边,fill =y)
self.canvas.pack(side =left,fill =both,expand = True)
self.canvas.create_windo w((4,4),window = self.frame)

self.bind(< Configure>,self.OnFrameConfigure)

elif name == TopWin:
self.pack()
tk.Label(self,text =FirstColTop,width = 30).grid(row = 0,column = 0)
tk.Label (self,text =SecndColTop,width = 20).grid(row = 0,column = 1)

def addrowTop(self,stuff,otherstuff):
global toprow

textfield = tk.Text(self,width = 30,height = 1)
textfield.grid(row = toprow,column = 0)
textfield.insert('0.0',东西)

textfield = tk.Text(self,width = 20,height = 1)
textfield.grid(row = toprow,column = 1)
textfield.insert '0.0',otherstuff)

toprow + = 1

def OnFrameConfigure(self,event):
self.canvas.configure(scrollregion = self.frame.bbox (all))

def addrowBot(self,stuff,otherstuff):
全球botrow

te xtfield = tk.Text(self,width = 30,height = 1)
textfield.grid(row = botrow,column = 0)
textfield.insert('0.0',stuff)

textfield = tk.Text(self,width = 20,height = 1)
textfield.grid(row = botrow,column = 1)
textfield.insert('0.0',otherstuff)

botrow + = 1

def SomeProg():
在范围内(20):
if i%2 == 0:
stuff =Stuff is+ str(i)
otherstuff = i * 3
Wins [0] .addrowTop(stuff,otherstuff)
elif i%2 == 1:
stuff =Stuff is+ str(i)
otherstuff = i * 4
Wins [1] .addrowBot(stuff,otherstuff)


root = tk.Tk()
root.title(Stuff)

Wins = [ProgramWindow(TopWin),ProgramWindow(BotWin)]
SomeProg )

root.mainloop()


解决方案

为了适应布赖恩奥克利的答案针对您的具体问题:


  • 用画布作为父母创建您的框架

  • 使用canvas作为参数 scrollregion



注意:当子类化在python中,你不需要存储父节点 __ init __ 的结果,因为它是在self上运行的。



补丁:

  def __init __(self,name):
self.name = name
- self .frame = tk.Frame .__ init __(self,root)

if name ==BotWin:
+ self.canvas = tk.Canvas(root,borderwidth = 0,background = #ffffff)
+ tk.Frame .__ init __(self,self.canvas)
tk.Label(self,text =FirstColBot,width = 30).grid(row = 0,column = 0)
tk.Label(self,text =SecndColBot,width = 20).grid(row = 0,column = 1)
- self.canvas = tk.Canvas(root,borderwidth = 0,background =#ffffff)
self.vsb = tk.Scrollbar(root,orient =vertical,command = self.canvas.yview)
self.canvas.configure(yscrollcommand = self.vsb.set)

self.vsb .pack(side =right,fill =y)
self.canvas.pack(side =left,fill =both,expand = True)
- self.canvas。 create_window((4,4),window = self.frame)
+ self.canvas.create_window((4,4),window = self)
self.bind(< Configure> self.OnFrameConfigure)

elif name ==TopWin:
+ self.frame = tk.Frame .__ init __(self,root)
self.pack()
tk.Label(self,text =SecndColTop,width = 20)。
tk.Label(self,text =FirstColTop,width = 30).grid(row = 0,column = 0)。 grid(row = 0,column = 1)
@@ -41,7 +40,7 @@
toprow + = 1

OnFrameConfigure(self,event):
- self.canvas.configure(scrollregion = self.frame.bbox(all))
+ self.canvas.configure(scrollregion = self.canvas.bbox(all))

def addrowBot(self,stuff,otherstuff):
全局botrow


Possible Duplicate:
Adding a scrollbar to a grid of widgets in Tkinter

On my project, i want do display my results in a window, using Tkinter as GUI. I place them in a kind of table, using the grid widget, and the window is separated in two different parts (for different results). But after longer runs, the number of results displayed exceed the height of my screen, so i want to add a scrollbar to my program. I already looked into several questions here on stackoverflow, and the answer that has come closest was this:

Adding a scrollbar to a group of widgets in Tkinter (just to let You know what I am axactly looking for!)

I am not able to apply that to my program though, maybe because I am rather new to Python and sometimes think i am a Dr. Frankenstein with tutorial-examples.

I tried a lot now, but i cant get the tables to be displayed in the canvas, possibly just some little thing i am missing.

I created an abstract example of my program (without scrollbar) so You know what I am working with, maybe someone of You can help my getting that scrollbar where it belongs!

Thank You very much!

example code: (runs)

import Tkinter as tk
toprow=1
botrow=1
class ProgramWindow(tk.Frame): 

    def __init__(self,name): 
        self.name = name
        tk.Frame.__init__(self,root)
        self.pack()

        if name=="BotWin":
            tk.Label(self,text="FirstColBot",width=30).grid(row=0,column=0)            
            tk.Label(self,text="SecndColBot",width=20).grid(row=0,column=1)

        elif name=="TopWin":
            tk.Label(self,text="FirstColTop",width=30).grid(row=0,column=0)         
            tk.Label(self,text="SecndColTop",width=20).grid(row=0,column=1)

    def addrowTop(self,stuff,otherstuff):
        global toprow

        textfield = tk.Text(self,width=30,height=1)
        textfield.grid(row=toprow,column=0)
        textfield.insert('0.0',stuff)

        textfield = tk.Text(self,width=20,height=1)
        textfield.grid(row=toprow,column=1)
        textfield.insert('0.0',otherstuff)

        toprow+=1

    def addrowBot(self,stuff,otherstuff):
        global botrow

        textfield = tk.Text(self,width=30,height=1)
        textfield.grid(row=botrow,column=0)
        textfield.insert('0.0',stuff)

        textfield = tk.Text(self,width=20,height=1)
        textfield.grid(row=botrow,column=1)
        textfield.insert('0.0',otherstuff)

        botrow+=1

def SomeProg():
    for i in range(20):
        if i%2==0:
            stuff = "Stuff is "+str(i)
            otherstuff=i*3
            Wins[0].addrowTop(stuff,otherstuff)
        elif i%2==1:
            stuff = "Stuff is "+str(i)
            otherstuff=i*4
            Wins[1].addrowBot(stuff,otherstuff)


root = tk.Tk()
root.title("Stuff")

Wins = [ ProgramWindow("TopWin"),ProgramWindow("BotWin")]
SomeProg()

root.mainloop()

additional code with my tries to add the scrollbar (based on example shown in link above). if the scrollbar is only shown in the lower part, that would be okay since thats the part with the many results.)

import Tkinter as tk
toprow=1
botrow=1
class ProgramWindow(tk.Frame): 

    def __init__(self,name): 
        self.name = name
        self.frame=tk.Frame.__init__(self,root)


        if name=="BotWin":
            tk.Label(self,text="FirstColBot",width=30).grid(row=0,column=0)            
            tk.Label(self,text="SecndColBot",width=20).grid(row=0,column=1)

            self.canvas = tk.Canvas(root, borderwidth=0, background="#ffffff")
            self.vsb = tk.Scrollbar(root, orient="vertical", command=self.canvas.yview)
            self.canvas.configure(yscrollcommand=self.vsb.set)

            self.vsb.pack(side="right", fill="y")
            self.canvas.pack(side="left", fill="both", expand=True)
            self.canvas.create_window((4,4), window=self.frame)

            self.bind("<Configure>", self.OnFrameConfigure)

        elif name=="TopWin":
            self.pack()
            tk.Label(self,text="FirstColTop",width=30).grid(row=0,column=0)         
            tk.Label(self,text="SecndColTop",width=20).grid(row=0,column=1)

    def addrowTop(self,stuff,otherstuff):
        global toprow

        textfield = tk.Text(self,width=30,height=1)
        textfield.grid(row=toprow,column=0)
        textfield.insert('0.0',stuff)

        textfield = tk.Text(self,width=20,height=1)
        textfield.grid(row=toprow,column=1)
        textfield.insert('0.0',otherstuff)

        toprow+=1

    def OnFrameConfigure(self, event):
        self.canvas.configure(scrollregion=self.frame.bbox("all"))

    def addrowBot(self,stuff,otherstuff):
        global botrow

        textfield = tk.Text(self,width=30,height=1)
        textfield.grid(row=botrow,column=0)
        textfield.insert('0.0',stuff)

        textfield = tk.Text(self,width=20,height=1)
        textfield.grid(row=botrow,column=1)
        textfield.insert('0.0',otherstuff)

        botrow+=1

def SomeProg():
    for i in range(20):
        if i%2==0:
            stuff = "Stuff is "+str(i)
            otherstuff=i*3
            Wins[0].addrowTop(stuff,otherstuff)
        elif i%2==1:
            stuff = "Stuff is "+str(i)
            otherstuff=i*4
            Wins[1].addrowBot(stuff,otherstuff)


root = tk.Tk()
root.title("Stuff")

Wins = [ ProgramWindow("TopWin"),ProgramWindow("BotWin")]
SomeProg()

root.mainloop()

解决方案

To adapt Bryan Oakley's answer to your specific problem:

  • create your frame with the canvas as parent
  • use the canvas as the parameter of scrollregion

Note: when subclassing in python, you do not need to store the result of parent __init__ since it operate on self.

Here is the patch:

     def __init__(self,name): 
         self.name = name
-        self.frame=tk.Frame.__init__(self,root)

         if name=="BotWin":
+            self.canvas = tk.Canvas(root, borderwidth=0, background="#ffffff")
+            tk.Frame.__init__(self,self.canvas)
             tk.Label(self,text="FirstColBot",width=30).grid(row=0,column=0)            
             tk.Label(self,text="SecndColBot",width=20).grid(row=0,column=1)
-            self.canvas = tk.Canvas(root, borderwidth=0, background="#ffffff")
             self.vsb = tk.Scrollbar(root, orient="vertical", command=self.canvas.yview)
             self.canvas.configure(yscrollcommand=self.vsb.set)

             self.vsb.pack(side="right", fill="y")
             self.canvas.pack(side="left", fill="both", expand=True)
-            self.canvas.create_window((4,4), window=self.frame)
+            self.canvas.create_window((4,4), window=self)
             self.bind("<Configure>", self.OnFrameConfigure)

         elif name=="TopWin":
+            self.frame=tk.Frame.__init__(self,root)
             self.pack()
             tk.Label(self,text="FirstColTop",width=30).grid(row=0,column=0)         
             tk.Label(self,text="SecndColTop",width=20).grid(row=0,column=1)
@@ -41,7 +40,7 @@
         toprow+=1

     def OnFrameConfigure(self, event):
-        self.canvas.configure(scrollregion=self.frame.bbox("all"))
+        self.canvas.configure(scrollregion=self.canvas.bbox("all"))

     def addrowBot(self,stuff,otherstuff):
         global botrow

这篇关于Tkinter网格中的滚动条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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