[Tkinter] How to add a AutoScrollbar ?

Post here if you need help with creating a Graphical User Interface in Python.

[Tkinter] How to add a AutoScrollbar ?

Postby eslavko » Sat Dec 28, 2013 3:37 pm

Hello...

in below example (stripped from larger program) I got grid of element. The grid is scrolable left-right. When I click Append line button I got new line. When there is enought lines I wan't vertical scrollbar too. (it works if I put enought elements before running program. Same is when I resize window the scrollbar doesen't wor. as should.

Some help?

Code: Select all
from Tkinter import *


class AutoScrollbar(Scrollbar):
    # a scrollbar that hides itself if it's not needed.  only
    # works if you use the grid geometry manager.
    def set(self, lo, hi):
        if float(lo) <= 0.0 and float(hi) >= 1.0:
            # grid_remove is currently missing from Tkinter!
            self.tk.call("grid", "remove", self)
        else:
            self.grid()
        Scrollbar.set(self, lo, hi)
    def pack(self, **kw):
        raise TclError, "cannot use pack with this widget"
    def place(self, **kw):
        raise TclError, "cannot use place with this widget"
   
def addRung():
    rungs.append([])
    r=len(rungs)-1
    for c in range(12):
        lader.rowconfigure(r, weight=1)
        lader.columnconfigure(c, weight=1)
        rungs[r].append([])
        rungs[r][-1]=(Canvas(lader,bg="white", height=50, width=50,highlightthickness=0))       
        rungs[r][-1].grid(row=r,column=c,sticky=W+E+N+S)
        rungs[r][-1].create_line(0,0,100,0,fill="azure2")
        rungs[r][-1].create_line(0,0,0,100,fill="azure2")
        rungs[r][-1].create_text(0,0, text=str(r)+'/'+str(c), fill="blue", anchor=NW)

rungs=[]

root = Tk()
orodja = Frame(root)
orodja.grid(row=0,column=0,sticky=W+E+N+S)

button= Button(orodja,text ="Append line",command = addRung)
button.grid()

laderF = Frame(root,bd=2,relief=RAISED)
laderF.grid(row=0,column=1,sticky=W+E+N+S)
vscrollbar = AutoScrollbar(laderF)
vscrollbar.grid(row=0, column=1, sticky=N+S)
hscrollbar = AutoScrollbar(laderF, orient=HORIZONTAL)
hscrollbar.grid(row=1, column=0, sticky=E+W)
frameCanvas = Canvas(laderF,yscrollcommand=vscrollbar.set,xscrollcommand=hscrollbar.set)
frameCanvas.grid(row=0, column=0, sticky=N+S+E+W)
vscrollbar.config(command=frameCanvas.yview)
hscrollbar.config(command=frameCanvas.xview)
laderF.grid_rowconfigure(0, weight=1)
laderF.grid_columnconfigure(0, weight=1)
lader = Frame(frameCanvas)
lader.rowconfigure(1, weight=1)
lader.columnconfigure(1, weight=1)

addRung()
addRung()
addRung()


frameCanvas.create_window(0, 0, anchor=NW, window=lader)
lader.update_idletasks()
frameCanvas.config(scrollregion=frameCanvas.bbox("all"))


root.mainloop()
Last edited by Yoriz on Sat Dec 28, 2013 4:02 pm, edited 2 times in total.
Reason: changed title and moved to gui topic
eslavko
 
Posts: 25
Joined: Thu Dec 26, 2013 10:23 am

Re: [Tkinter] How to add a AutoScrollbar ?

Postby Yoriz » Sat Dec 28, 2013 4:04 pm

Be aware that you are adding functionality to tkinter that comes for free with other gui frameworks.
New Users, Read This
Join the #python-forum IRC channel on irc.freenode.net!
Spam topic disapproval technician
Windows7, Python 2.7.4., WxPython 2.9.5.0., some Python 3.3
User avatar
Yoriz
 
Posts: 781
Joined: Fri Feb 08, 2013 1:35 am
Location: UK

Re: [Tkinter] How to add a AutoScrollbar ?

Postby eslavko » Sat Dec 28, 2013 5:39 pm

...Actualy something is wrong in my code too.
Here is example for adding lines. If I add lines to the end the result is ok. But if I insert lines then something doesn't work ok.
Some ideas?

Code: Select all
from Tkinter import *


def addRung():

#This variant works
#    rungs.append([])
#    r=len(rungs)-1
   
#this variant doesn't work   
    rungs.insert(0,([]))
    r=0
   
   

    for c in range(12):
        lader.rowconfigure(r, weight=1)
        lader.columnconfigure(c, weight=1)
        rungs[r].append([])
        rungs[r][-1]=(Canvas(lader,bg="white", height=50, width=50,highlightthickness=0))       
        rungs[r][-1].grid(row=r,column=c,sticky=W+E+N+S)
        rungs[r][-1].create_line(0,0,100,0,fill="azure2")
        rungs[r][-1].create_line(0,0,0,100,fill="azure2")
        rungs[r][-1].create_text(0,0, text=str(r)+'/'+str(c), fill="blue", anchor=NW)
       
    print "Rungs present ",len(rungs)   

rungs=[]

root = Tk()
orodja = Frame(root)
orodja.grid(row=0,column=0,sticky=W+E+N+S)

button= Button(orodja,text ="Append line",command = addRung)
button.grid()

lader = Frame(root,bd=2,relief=RAISED)
lader.grid(row=0,column=1,sticky=W+E+N+S)

addRung()
addRung()
addRung()

root.mainloop()
eslavko
 
Posts: 25
Joined: Thu Dec 26, 2013 10:23 am

Re: [Tkinter] How to add a AutoScrollbar ?

Postby wuf » Sun Dec 29, 2013 9:32 am

Hi eslavko

Try the following:
Code: Select all
from Tkinter import *


class AutoScrollbar(Scrollbar):
    # a scrollbar that hides itself if it's not needed.  only
    # works if you use the grid geometry manager.
    def set(self, lo, hi):
        if float(lo) <= 0.0 and float(hi) >= 1.0:
            # grid_remove is currently missing from Tkinter!
            self.tk.call("grid", "remove", self)
        else:
            self.grid()
        Scrollbar.set(self, lo, hi)
    def pack(self, **kw):
        raise TclError, "cannot use pack with this widget"
    def place(self, **kw):
        raise TclError, "cannot use place with this widget"

def update():
    frameCanvas.update_idletasks()
    if frameCanvas.bbox('all') != None:
        x0, y0, x1, y1 = frameCanvas.bbox('all')
    else:
        # Hide scrollbars
        frameCanvas.config(scrollregion=(0, 0, 0, 0))
        return

    #~~ Skaliere die Ziehleisten auf den neuen Canvas-Inhalt   
    region = (x0, y0, x1, y1)
    frameCanvas.config(scrollregion=region)
       
def addRung():
    rungs.append([])
    r=len(rungs)-1
    for c in range(12):
        lader.rowconfigure(r, weight=1)
        lader.columnconfigure(c, weight=1)
        rungs[r].append([])
        rungs[r][-1]=(Canvas(lader,bg="white", height=50, width=50,highlightthickness=0))       
        rungs[r][-1].grid(row=r,column=c,sticky=W+E+N+S)
        rungs[r][-1].create_line(0,0,100,0,fill="azure2")
        rungs[r][-1].create_line(0,0,0,100,fill="azure2")
        rungs[r][-1].create_text(0,0, text=str(r)+'/'+str(c), fill="blue", anchor=NW)
    update()
rungs=[]

root = Tk()
orodja = Frame(root)
orodja.grid(row=0,column=0,sticky=W+E+N+S)

button= Button(orodja,text ="Append line",command = addRung)
button.grid()

laderF = Frame(root,bd=2,relief=RAISED)
laderF.grid(row=0,column=1,sticky=W+E+N+S)

vscrollbar = AutoScrollbar(laderF)
vscrollbar.grid(row=0, column=1, sticky=N+S)

hscrollbar = AutoScrollbar(laderF, orient=HORIZONTAL)
hscrollbar.grid(row=1, column=0, sticky=E+W)

frameCanvas = Canvas(laderF,yscrollcommand=vscrollbar.set,xscrollcommand=hscrollbar.set)
frameCanvas.grid(row=0, column=0, sticky=N+S+E+W)

vscrollbar.config(command=frameCanvas.yview)
hscrollbar.config(command=frameCanvas.xview)
laderF.grid_rowconfigure(0, weight=1)
laderF.grid_columnconfigure(0, weight=1)
lader = Frame(frameCanvas)
lader.rowconfigure(1, weight=1)
lader.columnconfigure(1, weight=1)

addRung()
addRung()
addRung()


frameCanvas.create_window(0, 0, anchor=NW, window=lader)
lader.update_idletasks()
frameCanvas.config(scrollregion=frameCanvas.bbox("all"))


root.mainloop()

wuf ;)
wuf
 
Posts: 37
Joined: Fri Feb 08, 2013 6:42 am

Re: [Tkinter] How to add a AutoScrollbar ?

Postby eslavko » Sun Dec 29, 2013 9:45 am

Thanks.
This solve one part of problem.
I don't know why doesn't work if I insert ung instead append?

The change the first two lines in addRung() from
rungs.append([])
r=len(rungs)-1

to
rungs.insert(0,[])
r=0

The aray's are filled properly but not displayed?!?
eslavko
 
Posts: 25
Joined: Thu Dec 26, 2013 10:23 am

Re: [Tkinter] How to add a AutoScrollbar ?

Postby wuf » Sun Dec 29, 2013 5:13 pm

Hi eslavko

This should work:
Code: Select all
def addRung():
    #rungs.append([])
    #r=len(rungs)-1
   
    rungs.insert(0,([]))
    r=len(rungs)-1

    for c in range(12):
        lader.rowconfigure(r, weight=1)
        lader.columnconfigure(c, weight=1)

        rungs[r].append([])
        canvas = Canvas(lader,bg="white", height=50, width=50,highlightthickness=0)
        canvas.grid(row=r,column=c,sticky=W+E+N+S)
        canvas.create_line(0,0,100,0,fill="azure2")
        canvas.create_line(0,0,0,100,fill="azure2")
        canvas.create_text(0,0, text=str(r)+'/'+str(c), fill="blue", anchor=NW)
        rungs[r][0].append(canvas)
       
#        rungs[r][0]=(Canvas(lader,bg="white", height=50, width=50,highlightthickness=0))       
#        rungs[r][0].grid(row=r,column=c,sticky=W+E+N+S)
#        rungs[r][0].create_line(0,0,100,0,fill="azure2")
#        rungs[r][0].create_line(0,0,0,100,fill="azure2")
#        rungs[r][0].create_text(0,0, text=str(r)+'/'+str(c), fill="blue", anchor=NW)
       
    update()

wuf ;)
wuf
 
Posts: 37
Joined: Fri Feb 08, 2013 6:42 am

Re: [Tkinter] How to add a AutoScrollbar ?

Postby eslavko » Sun Dec 29, 2013 6:42 pm

Thanks wuf, but if I understand how this work it will not work for my application.
I need to insert 'rung' in any place not only in [0].
And all rungs under that should be shifted one rung lower keeping own information.
Seems that I'm to naive.
Actualy I need to shift all Canvas in frame one line lower too. I just miss that rungs[] and Canvas doesnt stay in sync if I insert item somewhere in betwen rung.
If I have rung 0,1,2,3 and display show same, when I insert new one betwen 1 and 2 I need to shift rung[].grid(row=) too make room for new one! Or I miss something again.
eslavko
 
Posts: 25
Joined: Thu Dec 26, 2013 10:23 am


Return to GUI

Who is online

Users browsing this forum: No registered users and 2 guests