469,133 Members | 1,404 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,133 developers. It's quick & easy.

scrollbar dependencies

Hello.

I am using Tkinter and Pmw.
I would like to build 2 canvases/frames that are scrollable together
horizontally, and independently vertically (so, the vertical
scrollbars should not be moved by the horizontal one).

So I built a Pmw.ScrolledFrame() containing the 2 canvases,
horizontally scrollable. Now I am trying to build 2 independent
vertical scrollbars,
--> wich command is linked to each canvas (whose parent is
Pmw.ScrolledFrame.component('frame'),
--> and which parent is root (to be packed outside the Pmw.ScrolledFrame).

Is this possible or not ? If not, does somebody allready did that another way ?

Thanks a lot.

Marion.
Jul 18 '05 #1
7 1303
On 3 Mar 2005 01:06:48 -0800, Marion <su**********@gmail.com> wrote:
Hello.

I am using Tkinter and Pmw.
I would like to build 2 canvases/frames that are scrollable together
horizontally, and independently vertically (so, the vertical
scrollbars should not be moved by the horizontal one).

So I built a Pmw.ScrolledFrame() containing the 2 canvases,
horizontally scrollable.
I'd not go that way: a Pmw.ScrolledFrame is not supposed to be used this way, and you may have great troubles making it work as you want...

[snip] Is this possible or not ? If not, does somebody allready did that another way ?


Here is a solution using only pure-Tkinter:

--DualCanvas.py--------------------------------------------------
from Tkinter import *

## Main window
root = Tk()
root.grid_rowconfigure(0, weight=1)
root.grid_rowconfigure(1, weight=1)
root.grid_columnconfigure(0, weight=1)

## First canvas
c1 = Canvas(root, width=200, height=100, bd=2, relief=SUNKEN,
scrollregion=(0, 0, 500, 500))
c1.grid(row=0, column=0, sticky='nswe')

## Second canvas
c2 = Canvas(root, width=200, height=100, bd=2, relief=SUNKEN,
scrollregion=(0, 0, 500, 500))
c2.grid(row=1, column=0, sticky='nswe')

## Special function scroll both canvases horizontally
def xscrollboth(*args):
c1.xview(*args)
c2.xview(*args)

## Horizontal scrollbar for both canvases
hScroll = Scrollbar(root, orient=HORIZONTAL, command=xscrollboth)
hScroll.grid(row=2, column=0, sticky='we')

## Vertical scrollbars
vScroll1 = Scrollbar(orient=VERTICAL, command=c1.yview)
vScroll1.grid(row=0, column=1, sticky='ns')

vScroll2 = Scrollbar(orient=VERTICAL, command=c2.yview)
vScroll2.grid(row=1, column=1, sticky='ns')

## Associate scrollbars to canvases
c1.configure(xscrollcommand=hScroll.set, yscrollcommand=vScroll1.set)
c2.configure(xscrollcommand=hScroll.set, yscrollcommand=vScroll2.set)

## Put a few things in canvases so that we see what's going on
c1.create_oval(80, 80, 120, 120, fill='red')
c1.create_oval(380, 80, 420, 120, fill='red')
c1.create_oval(80, 380, 120, 420, fill='red')
c1.create_oval(380, 380, 420, 420, fill='red')

c2.create_oval(80, 80, 120, 120, fill='blue')
c2.create_oval(380, 80, 420, 120, fill='blue')
c2.create_oval(80, 380, 120, 420, fill='blue')
c2.create_oval(380, 380, 420, 420, fill='blue')

## Go!
root.mainloop()
-----------------------------------------------------------------

The "trick" is simply to create a function accepting the same arguments as the xview methods on canvases and forward these arguments to the xview methods of both canvases. You then pass this function to the command option of both scrollbars, and voilą. The link canvas -> scrollbar is done the usual way.

HTH
--
python -c 'print "".join([chr(154 - ord(c)) for c in "U(17zX(%,5.z^5(17l8(%,5.Z*(93-965$l7+-"])'
Jul 18 '05 #2
Pardon a question I should already know the answer to, but what are the
*args in the:

def xscrollboth(*args):
c1.xview(*args)
c2.xview(*args)

Thanks,

Harlin

Jul 18 '05 #3
On 3 Mar 2005 02:38:59 -0800, Harlin Seritt <ha**********@yahoo.com> wrote:
Pardon a question I should already know the answer to, but what are the
*args in the:

def xscrollboth(*args):
c1.xview(*args)
c2.xview(*args)

Thanks,

Harlin


If your question is about the syntax, it's just the way of passing any number of arguments to a function as explained in:
http://docs.python.org/tut/node6.htm...00000000000000

If your question is about what will actually be passed in these arguments, the answer is simply: I don't know, and I don't care. That's why I used a *args: I just want to pass to the c1.xview and c2.xview methods exactly what was passed to my xscrollboth function. Since Python allows me to just pass the list of arguments unchanged, I happily do it.
--
python -c 'print "".join([chr(154 - ord(c)) for c in "U(17zX(%,5.z^5(17l8(%,5.Z*(93-965$l7+-"])'
Jul 18 '05 #4
Thanks a lot, Eric Brunel.
Harlin, if it's still actual (don't think so, but whoever...) here is
a simple code that works.
---------------------------------------
from Tkinter import *

## Main window
root = Tk()
root.grid_rowconfigure(0, weight=1)
root.grid_rowconfigure(1, weight=1)
root.grid_columnconfigure(0, weight=1)

## First canvas
c1 = Canvas(root, width=200, height=100, bd=2, relief=SUNKEN,
scrollregion=(0, 0, 500, 500))
c1.grid(row=0, column=0, sticky='nswe')

## Second canvas
c2 = Canvas(root, width=200, height=100, bd=2, relief=SUNKEN,
scrollregion=(0, 0, 500, 500))
c2.grid(row=1, column=0, sticky='nswe')

## Special function scroll both canvases horizontally
def xscrollboth(self,*args):
c1.xview(self,*args)
c2.xview(self,*args)

## Horizontal scrollbar for both canvases
hScroll = Scrollbar(root, orient=HORIZONTAL, command=xscrollboth)
hScroll.grid(row=2, column=0, sticky='we')

## Vertical scrollbars
vScroll1 = Scrollbar(orient=VERTICAL, command=c1.yview)
vScroll1.grid(row=0, column=1, sticky='ns')
c1.config(yscrollcommand=vScroll1.set,xscrollcomma nd=hScroll.set)

vScroll2 = Scrollbar(orient=VERTICAL, command=c2.yview)
vScroll2.grid(row=1, column=1, sticky='ns')
c2.config(yscrollcommand=vScroll2.set,xscrollcomma nd=hScroll.set)

root.mainloop()
---------------------------------------

"Eric Brunel" <er*********@despammed.com> wrote in message news:<op**************@eb.pragmadev>...
On 3 Mar 2005 02:38:59 -0800, Harlin Seritt <ha**********@yahoo.com> wrote:
Pardon a question I should already know the answer to, but what are the
*args in the:

def xscrollboth(*args):
c1.xview(*args)
c2.xview(*args)

Thanks,

Harlin


If your question is about the syntax, it's just the way of passing any number of arguments to a function as explained in:
http://docs.python.org/tut/node6.htm...00000000000000

If your question is about what will actually be passed in these arguments, the answer is simply: I don't know, and I don't care. That's why I used a *args: I just want to pass to the c1.xview and c2.xview methods exactly what was passed to my xscrollboth function. Since Python allows me to just pass the list of arguments unchanged, I happily do it.

Jul 18 '05 #5
Next mystery :
a picture drawn in the canvas c1 is scrollable.
a picture-containing canvas "grided" in the canvas c1 is not.

so why ???
Marion
---------------------------------------------------------------
from tkinter import *
from PIL import *

class Main:
def __init__(self):
## Main window
self.root = Tk()
self.root.grid_rowconfigure(0, weight=1)
self.root.grid_rowconfigure(1, weight=1)
self.root.grid_columnconfigure(0, weight=1)
## datas :
self.PIC=[]
self.ANN=[]

## First canvas (picture)
self.c1 = Canvas(
self.root,
width=500,
height=100,
bd=2,
relief=SUNKEN,
scrollregion=(0, 0, 100, 100))

self.c1.grid(
row=0,rowspan=2,
column=1,
sticky='nswe')

#-------------------------------#
# this is scrollable :
#-------------------------------#
image =Image.new("RGB",(100,100))
dessin = ImageDraw.Draw(image)
dessin.rectangle([(10,10),(50,50)],fill="rgb(255,0,0)")
photo=ImageTk.PhotoImage(image)
item = self.c1.create_image(0,0,anchor=NW,image=photo)

#-------------------------------#
# this is not ! :
#-------------------------------#
canvas=Canvas(self.c1,background="WHITE")
image =Image.new("RGB",(100,100))
dessin = ImageDraw.Draw(image)
dessin.rectangle([(10,10),(50,50)],fill="rgb(255,0,0)")
photo=ImageTk.PhotoImage(image)
item = canvas.create_image(0,0,anchor=NW,image=photo)
canvas.grid()
## Second canvas (annot)
c2 = Canvas(
self.root,
width=500,
height=100,
bd=2,
relief=SUNKEN,
scrollregion=(0, 0, 1000, 1000))
c2.grid(
row=2,rowspan=2,
column=1,
sticky='nswe')

## Special function scroll both canvases horizontally
def xscrollboth(a,*args):
self.c1.xview(a,*args)
c2.xview(a,*args)

## Horizontal scrollbar for both canvases
hScroll = Scrollbar(self.root, orient=HORIZONTAL, command=xscrollboth)
hScroll.grid(
row=4,rowspan=1,
column=1,
sticky='we')

## Vertical scrollbars
vScroll1 = Scrollbar(orient=VERTICAL, command=self.c1.yview)
vScroll1.grid(
row=0,rowspan=2,
column=2,
sticky='ns')
self.c1.config(yscrollcommand=vScroll1.set,xscroll command=hScroll.set)

vScroll2 = Scrollbar(orient=VERTICAL, command=c2.yview)
vScroll2.grid(
row=2,rowspan=2,
column=2,
sticky='ns')
c2.config(yscrollcommand=vScroll2.set,xscrollcomma nd=hScroll.set)
---------------------------------------------------------------
Jul 18 '05 #6
On 24 Mar 2005 03:24:34 -0800, Marion <su**********@gmail.com> wrote:
Next mystery :
a picture drawn in the canvas c1 is scrollable.
a picture-containing canvas "grided" in the canvas c1 is not.

so why ???
Marion
--------------------------------------------------------------- [snip] #-------------------------------#
# this is not ! :
#-------------------------------#
canvas=Canvas(self.c1,background="WHITE")
image =Image.new("RGB",(100,100))
dessin = ImageDraw.Draw(image)
dessin.rectangle([(10,10),(50,50)],fill="rgb(255,0,0)")
photo=ImageTk.PhotoImage(image)
item = canvas.create_image(0,0,anchor=NW,image=photo)
canvas.grid()


You don't want to do that. Canvases are not meant to be containers where you can pack or grid items. They strangely accept it, but it will never do what you want. If you want to pack or grid items in a container, use a Frame. If you want to include a widget in a Canvas, use a canvas window:
c1 = Canvas(root)
c1.pack()
c2 = Canvas(c1, bd=2, relief=SUNKEN, width=50, height=50)
c1.create_window(20, 20, window=c2, anchor=NW)


Canvas windows are scollable; widgets packed or gridded in Canvases are not. So this really seems to be your problem here.

HTH
--
python -c 'print "".join([chr(154 - ord(c)) for c in "U(17zX(%,5.z^5(17l8(%,5.Z*(93-965$l7+-"])'
Jul 18 '05 #7
ok, we must redefine each canvas scroll individually ... but what a ()
strange language... !!
Jul 18 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by Price Brattin | last post: by
9 posts views Thread by kjs | last post: by
reply views Thread by h-h | last post: by
reply views Thread by d.steininger | last post: by
2 posts views Thread by kurt sune | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.