scrollbar dependencies

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Marion

    #1

    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.ScrolledFra me() 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.ScrolledFra me.component('f rame'),
    --> and which parent is root (to be packed outside the Pmw.ScrolledFra me).

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

    Thanks a lot.

    Marion.
  • Eric Brunel

    #2
    Re: scrollbar dependencies

    On 3 Mar 2005 01:06:48 -0800, Marion <supermarion3@g mail.com> wrote:[color=blue]
    > 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.ScrolledFra me() containing the 2 canvases,
    > horizontally scrollable.[/color]

    I'd not go that way: a Pmw.ScrolledFra me is not supposed to be used this way, and you may have great troubles making it work as you want...

    [snip][color=blue]
    > Is this possible or not ? If not, does somebody allready did that another way ?[/color]

    Here is a solution using only pure-Tkinter:

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

    ## Main window
    root = Tk()
    root.grid_rowco nfigure(0, weight=1)
    root.grid_rowco nfigure(1, weight=1)
    root.grid_colum nconfigure(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(*ar gs):
    c1.xview(*args)
    c2.xview(*args)

    ## Horizontal scrollbar for both canvases
    hScroll = Scrollbar(root, orient=HORIZONT AL, command=xscroll both)
    hScroll.grid(ro w=2, column=0, sticky='we')

    ## Vertical scrollbars
    vScroll1 = Scrollbar(orien t=VERTICAL, command=c1.yvie w)
    vScroll1.grid(r ow=0, column=1, sticky='ns')

    vScroll2 = Scrollbar(orien t=VERTICAL, command=c2.yvie w)
    vScroll2.grid(r ow=1, column=1, sticky='ns')

    ## Associate scrollbars to canvases
    c1.configure(xs crollcommand=hS croll.set, yscrollcommand= vScroll1.set)
    c2.configure(xs crollcommand=hS croll.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+-"])'

    Comment

    • Harlin Seritt

      #3
      Re: scrollbar dependencies

      Pardon a question I should already know the answer to, but what are the
      *args in the:

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

      Thanks,

      Harlin

      Comment

      • Eric Brunel

        #4
        Re: scrollbar dependencies

        On 3 Mar 2005 02:38:59 -0800, Harlin Seritt <harlinseritt@y ahoo.com> wrote:
        [color=blue]
        > Pardon a question I should already know the answer to, but what are the
        > *args in the:
        >
        > def xscrollboth(*ar gs):
        > c1.xview(*args)
        > c2.xview(*args)
        >
        > Thanks,
        >
        > Harlin[/color]

        If your question is about the syntax, it's just the way of passing any number of arguments to a function as explained in:


        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+-"])'

        Comment

        • Marion

          #5
          Re: scrollbar dependencies

          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_rowco nfigure(0, weight=1)
          root.grid_rowco nfigure(1, weight=1)
          root.grid_colum nconfigure(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(sel f,*args):
          c1.xview(self,* args)
          c2.xview(self,* args)

          ## Horizontal scrollbar for both canvases
          hScroll = Scrollbar(root, orient=HORIZONT AL, command=xscroll both)
          hScroll.grid(ro w=2, column=0, sticky='we')

          ## Vertical scrollbars
          vScroll1 = Scrollbar(orien t=VERTICAL, command=c1.yvie w)
          vScroll1.grid(r ow=0, column=1, sticky='ns')
          c1.config(yscro llcommand=vScro ll1.set,xscroll command=hScroll .set)

          vScroll2 = Scrollbar(orien t=VERTICAL, command=c2.yvie w)
          vScroll2.grid(r ow=1, column=1, sticky='ns')
          c2.config(yscro llcommand=vScro ll2.set,xscroll command=hScroll .set)

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

          "Eric Brunel" <eric_brunel@de spammed.com> wrote in message news:<opsm177d1 crqur0o@eb.prag madev>...[color=blue]
          > On 3 Mar 2005 02:38:59 -0800, Harlin Seritt <harlinseritt@y ahoo.com> wrote:
          >[color=green]
          > > Pardon a question I should already know the answer to, but what are the
          > > *args in the:
          > >
          > > def xscrollboth(*ar gs):
          > > c1.xview(*args)
          > > c2.xview(*args)
          > >
          > > Thanks,
          > >
          > > Harlin[/color]
          >
          > 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.[/color]

          Comment

          • Marion

            #6
            Re: scrollbar dependencies

            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.rectangl e([(10,10),(50,50)],fill="rgb(255, 0,0)")
            photo=ImageTk.P hotoImage(image )
            item = self.c1.create_ image(0,0,ancho r=NW,image=phot o)

            #-------------------------------#
            # this is not ! :
            #-------------------------------#
            canvas=Canvas(s elf.c1,backgrou nd="WHITE")
            image =Image.new("RGB ",(100,100) )
            dessin = ImageDraw.Draw( image)
            dessin.rectangl e([(10,10),(50,50)],fill="rgb(255, 0,0)")
            photo=ImageTk.P hotoImage(image )
            item = canvas.create_i mage(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,*arg s)

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

            ## Vertical scrollbars
            vScroll1 = Scrollbar(orien t=VERTICAL, command=self.c1 .yview)
            vScroll1.grid(
            row=0,rowspan=2 ,
            column=2,
            sticky='ns')
            self.c1.config( yscrollcommand= vScroll1.set,xs crollcommand=hS croll.set)

            vScroll2 = Scrollbar(orien t=VERTICAL, command=c2.yvie w)
            vScroll2.grid(
            row=2,rowspan=2 ,
            column=2,
            sticky='ns')
            c2.config(yscro llcommand=vScro ll2.set,xscroll command=hScroll .set)
            ---------------------------------------------------------------

            Comment

            • Eric Brunel

              #7
              Re: scrollbar dependencies

              On 24 Mar 2005 03:24:34 -0800, Marion <supermarion3@g mail.com> wrote:
              [color=blue]
              > 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
              > ---------------------------------------------------------------[/color]
              [snip][color=blue]
              > #-------------------------------#
              > # this is not ! :
              > #-------------------------------#
              > canvas=Canvas(s elf.c1,backgrou nd="WHITE")
              > image =Image.new("RGB ",(100,100) )
              > dessin = ImageDraw.Draw( image)
              > dessin.rectangl e([(10,10),(50,50)],fill="rgb(255, 0,0)")
              > photo=ImageTk.P hotoImage(image )
              > item = canvas.create_i mage(0,0,anchor =NW,image=photo )
              > canvas.grid()[/color]

              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:
              [color=blue][color=green][color=darkred]
              >>> c1 = Canvas(root)
              >>> c1.pack()
              >>> c2 = Canvas(c1, bd=2, relief=SUNKEN, width=50, height=50)
              >>> c1.create_windo w(20, 20, window=c2, anchor=NW)[/color][/color][/color]

              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+-"])'

              Comment

              • Marion

                #8
                Re: scrollbar dependencies

                ok, we must redefine each canvas scroll individually ... but what a ()
                strange language... !!

                Comment

                Working...