0

I'm trying to build a dashboard.

I want to keep the scrollbar just for the canvas area, but, on the contrary, it just stick to other frame.

The code I have written is this

# python dashboard
import tkinter as tk
from tkinter import *


class AutoScrollbar(Scrollbar):
    def set(self, lo, hi):
        if float(lo) <= 0.0 and float(hi) >= 1.0:
            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")


class Dashboard():
    def __init__(self, root):
        self.root=root
        root.title("Dashboard View")

        vsb = AutoScrollbar(root)
        vsb.grid(row=0, column=1, sticky=N+S)
        hsb = AutoScrollbar(root, orient=HORIZONTAL)
        hsb.grid(row=1, column=0, sticky=E+W)

        self.canvas=tk.Canvas(root,yscrollcommand=vsb.set,
            xscrollcommand=hsb.set,background='blue')

        vsb.config(command=self.canvas.yview)
        hsb.config(command=self.canvas.xview)

        root.grid_rowconfigure(0, weight=1)
        root.grid_columnconfigure(0, weight=1)

        self.canvas.grid(row=0,column=3)
        frame = Frame(self.root, bd=2, relief=SUNKEN)
        frame.grid(row=0,column=0, sticky="nw")
        Button1=Button(frame,text="Status").grid(row = 0,column = 0, sticky = "we")
        Button2=Button(frame,text="Processes").grid(row = 0,column = 1, sticky = "we")
        Button3=Button(frame,text="Links").grid(row = 1,column = 0, sticky = "we")
        Button4=Button(frame,text="Traffic").grid(row = 1,column = 1, sticky = "we")
        Button5=Button(frame,text="App Version").grid(row = 2,column = 0, sticky = "we")
        Button5=Button(frame,text="Archive/Purge").grid(row = 2,column = 1, sticky = "we")

        fhandle = open("dashboard_content.txt")
        lines = fhandle.read()
        fhandle.close()
        text1=self.canvas.create_text(400, 400, fill="white")
        self.canvas.itemconfig(text1, text=lines)

        frame.update_idletasks()

        self.canvas.config(scrollregion=self.canvas.bbox("all"))

if __name__== '__main__':
    root=tk.Tk()
    board=Dashboard(root)
    root.mainloop()

How can I get the scrollbar just for the Canvas window, "to the blue background"?

nbro
  • 15,395
  • 32
  • 113
  • 196
jagpreet
  • 53
  • 1
  • 10

2 Answers2

0

I'm guessing you mean you want to leave all of the blank space surrounding the canvas, but you want the scrollbar to "stick" to the side of the canvas.

The easiest way to accomplish that is to put both the canvas and the scrollbars in a frame so that they act as a single unit.

For example:

class Dashboard():
    def __init__(self, root):
        ....
        canvasContainer = tk.Frame(root)
        self.canvas = tk.Canvas(canvasContainer, ...)
        vsb = AutoScrollbar(canvasContainer, ...)
        hsb = AutoScrollbar(canvasContainer, ...)
        vsb.grid(row=0, column=0, sticky="ns")
        hsb.grid(row=1, column=1, sticky="ew")
        self.canvas.grid(row=0, column=1, sticky="nsew")
        canvasContainer.grid_rowconfigure(0, weight=1)
        canvasContainer.grid_columnconfigure(1, weight=0)
        ...
        canvasContainer.grid(row=0, column=3)
        ...
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
0

@Bryan , Well all I wanted was to stick the scrollbar to the canvas area only and a sidebar on the left with buttons. With a bit modification to your suggestion I could manage to achieve. Here is what I did.

    # python dashboard

import tkinter as tk
from tkinter import *

class AutoScrollbar(Scrollbar):
    def set(self, lo, hi):
        if float(lo) <= 0.0 and float(hi) >= 1.0:
            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")

class Dashboard():
    def __init__(self, root):
        self.root=root
        root.title("Dashboard View")

        canvasContainer = tk.Frame(root)
        self.canvas=tk.Canvas(canvasContainer,background='blue')

        fhandle = open("dashboard_content.txt")
        lines = fhandle.read()
        fhandle.close()

        text1=self.canvas.create_text(400, 400, fill="white")
        self.canvas.itemconfig(text1, text=lines)

        vsb = AutoScrollbar(canvasContainer,orient=VERTICAL)
        hsb = AutoScrollbar(canvasContainer, orient=HORIZONTAL)
        vsb.grid(row=0, column=2, sticky="ns")
        hsb.grid(row=1, column=1, sticky="ew")
        self.canvas.grid(row=0,column=1,sticky="news")
        self.canvas.config(yscrollcommand=vsb.set, xscrollcommand=hsb.set, scrollregion=self.canvas.bbox("all"))


        vsb.config(command=self.canvas.yview)
        hsb.config(command=self.canvas.xview)

        canvasContainer.grid_rowconfigure(0, weight=1)
        canvasContainer.grid_columnconfigure(0, weight=1)

        canvasContainer.grid(row=0,column=3)
        frame = Frame(self.root, bd=2, relief=SUNKEN)
        frame.grid(row=0,column=0, sticky="nw")
        Button1=Button(frame,text="Status").grid(row = 0,column = 0, sticky = "we")
        Button2=Button(frame,text="Processes").grid(row = 0,column = 1, sticky = "we")
        Button3=Button(frame,text="Links").grid(row = 1,column = 0, sticky = "we")
        Button4=Button(frame,text="Traffic").grid(row = 1,column = 1, sticky = "we")
        Button5=Button(frame,text="App Version").grid(row = 2,column = 0, sticky = "we")
        Button5=Button(frame,text="Archive/Purge").grid(row = 2,column = 1, sticky = "we")

        self.canvas.update_idletasks()
#        Grid.columnconfigure(self.root,1,weight=1, minsize=100)

if __name__== '__main__':
    root=tk.Tk()
    board=Dashboard(root)
    root.mainloop()

Any idea, How can I make the complete window expandable.

jagpreet
  • 53
  • 1
  • 10