1

Creating a program that will place an image onto a canvas. I want to add an X-axis, and Y-axis scrollbar onto the canvas, but I am not sure how to.

I would normally use a Frame, but the program I'm working on is using tkinter.Toplevel instead of using a Frame.

#----- Imports ---------------------
import os
import os.path
import sys

import tkinter
tk = tkinter
from tkinter import font

#----- Set flag for JPEG support ---
noJPEG = False
try:
    from PIL import Image
    Pimg = Image
    from PIL import ImageDraw
    Pdraw = ImageDraw.Draw
    from PIL import ImageTk
    Pimgtk = ImageTk
except ImportError:
    noJPEG = True
#

#------------------------------------
# Create an invisible global parent window to hold all children.
# Facilitates easy closing of all windows by a mouse click.
_root = tk.Tk()
_root.withdraw()
#


#------------------------------------
# A writeable window for holding an image.
#
class ImageView(tk.Canvas):

    def __init__(self, image, title=''):
        master = tk.Toplevel(_root)
        master.protocol("WM_DELETE_WINDOW", self.close)
        tk.Canvas.__init__(self, master,
                           width = 600, height = 500,
                           scrollregion=(0,0, image.getWidth(),
                                         image.getHeight()))

        # Define class fields
        ## Image properties
        self.master.title(title)
        self.pack()
        master.resizable(0,0)
        self.foreground = "black"
        self.image = image
        self.height = image.getHeight()
        self.width = image.getWidth()
        # for later
        #self.customFont = font.Font(family="Helvetica", size=12)

        ## Actionable items
        self.mouseX = None
        self.mouseY = None
        self.mouseFxn = None
        self.bind("<Button-1>", self.onClick)  #bind action to button1 click
        self.tags = None

        _root.update()  #redraw global window
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
goofenhour
  • 159
  • 1
  • 2
  • 13
  • Why don't you just put a Frame in your Toplevel window? Maybe [this](http://stackoverflow.com/a/31763876/4014959) will help. – PM 2Ring Nov 02 '15 at 14:50
  • Could you explain a little more? I am not quite following. – goofenhour Nov 02 '15 at 15:14
  • I'm suggesting that you put a Frame into the Toplevel window and put a Canvas and Scrollbars into that Frame. – PM 2Ring Nov 02 '15 at 15:28
  • Could you help get me started? I'm looking up "how to put Frame into Toplevel window", but I'm not getting a lot of results. – goofenhour Nov 02 '15 at 16:07
  • 1
    A Toplevel widget is simply a container for other widgets, much like a Frame widget is. So if you know how to put widgets in a Frame then you already know how to put widgets in a Toplevel. – PM 2Ring Nov 02 '15 at 16:15
  • 1
    There's no reason to put a frame in a toplevel window just to get scrollbars. – Bryan Oakley Nov 02 '15 at 20:59

1 Answers1

2

There's nothing special about using a Toplevel rather than a Frame. You attach a scrollbar the way you do it for any scrollable widget in any container.

I've never seen a widget create it's own parent. That's quite unusual, though it really doesn't change anything. Just add the scrollbars inside the toplevel.

You might want to switch to grid instead of pack since that makes it a bit easier to get the scrollbars to line up properly. You just need to remove the call to self.pack(), and add something like this to your code:

vsb = tk.Scrollbar(master, orient="vertical", command=self.yview)
hsb = tk.Scrollbar(master, orient="horizontal", command=self.xview)
self.configure(yscrollcommand=vsb.set, xscrollcommand=hsb.set)

self.grid(row=0, column=0, sticky="nsew")
vsb.grid(row=0, column=1, sticky="ns")
hsb.grid(row=1, column=0, sticky="ew")
master.grid_rowconfigure(0, weight=1)
master.grid_columnconfigure(0, weight=1)
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • Thank you so much, Bryan Oakley! I've been struggling for quite awhile on how to solve this. I can't wait to show my instructor this! – goofenhour Nov 03 '15 at 00:11