0

I have the following code:

from win32com.client import Dispatch
from tkinter import *
from tkinter import ttk
import tkinter

class applicazione:

def __init__(self, root):
    self.root = root
    self.root.title('Controllo dati per fatturazione elettronica - Manticle - Smith & Nephew Italia')
    ttk.Frame(self.root, width=300, height=250).pack()






    #### label list
    self.titoli = list()
    self.titoli_BFT = ["Num_Doc", "Cod_Art", "Unita Misura", "Tot_Prod", "Quant_Prod", "Perc_IVA_Prod", "Tot_IVA_Prod",
                       "Linea_Prod", "Sconto", "Perc_Sconto", "Tipo_Sconto", "Cod_Art2", "Desc_Art"]
    self.titoli_HFT = ["Dest_Cod_FIS_P_Iva", "Cod_Cli", "Dest_RagSoc1", "Dest_RagSoc2",
                       "Dest_Indirizzo", "Dest_CAP", "Dest_Localita", "Dest_Provincia", "Cli_Cod_Fis_P_Iva",
                        "Cod_Dest", "Cli_RagSoc1", "Cli_RagSoc2", "Cli_Indirizzo", "Cli_CAP",
                       "Cli_Localita", "Cli_Provincia", "Tipo_Doc", "pre_Num_Doc", "Num_Doc",
                        "Data_Doc", "Vs_Rif", "Data_Rif", "Blank", "Blank2", "CPT", "Scad_Pagamento",
                       "Descr", "Num_Ord", "Tot_Imp", "Tot_IVA", "Tot_Doc", "Nazione", "IPA", "Reg_Fiscale"]

    self.titoli_IVA = ["Num_Doc_TMP", "Num_Doc", "Imponibile", "IVA, Tot", "Perc_IVA"]

    self.titoli_RIF_DOC = [ "Num_Doc_TMP", "Num_Doc", "Rif_Doc" ]

    self.titoli_RIF_DOC_BFT = ["Num_Doc_TMP", "Num_Doc", "Cod_Art", "NOTE" ]

    self.titoli_anomalieBFT = ["ordine", "anomalia"]

    self.titoli_anomalieHFT = ["ordine", "anomalia"]

    self.inizializza_widgets()
    self.lettura()



def inizializza_widgets(self):
    #label 

    self.lblins=tkinter.Label(self.root, text="Controllo dati per fatturazione elettronica", font=("Helvetica", 12))
    self.lblins.place(x=10, y=10



    for i in range (0,len(self.titoli_HFT)):
        j = 80*i
        self.lblnome=tkinter.Label(self.root, text= self.titoli_HFT[i], font=("Helvetica", 8))
        self.lblnome.place(x=85+j, y=50)


    #buttons

    ttk.Button(self.root, , text='Inserisci', width='10').place(x=645, y=590)
    #pulsante lettura
    ttk.Button(self.root, text='Modifica', width='10').place(x=725, y=590)

    ttk.Button(self.root, text='Indietro', width='10').place(x=805, y=590)

    ttk.Button(self.root, text='Avanti', width='10').place(x=885, y=590)


def onFrameConfigure(self, event):
    '''Reset the scroll region to encompass the inner frame'''
    self.canvas.configure(scrollregion=self.canvas.bbox("all"))

def lettura(self):
        xl= Dispatch("Excel.Application")
        xl.Visible = True


        self.checkb_intvar = list()   #contiene una lista di 1 o 0 associati alle checkbox nella lista quadratini
        self.quadratiniB = l = [None] * (13 * len(self.titoli_BFT) )
        self.quadratiniH = l = [None] * (13 * len(self.titoli_HFT) )


        wbH = xl.Workbooks.Open(r'C:\Users\\Marco\\LAVORO\\Smith&Nephew\\appRonca\\fonte\\HFT_SAP_2.csv')
        print("wbH")

        wsH=wbH.WorkSheets(1) # get a reference to the first sheet


        cont = 0

        MAX = 3  #13 lunghezza visibile senza barra navigatrice del numero di righe nella finestra 13
        cont = 0
        for i in range(0, MAX):
            for j in range(0,len(self.titoli_HFT)):
                print("for for")
                cont = cont + 1
                print("i")
                print(i)
                print("j")
                print(j)

                print(" The {} set is often represented as {{0}} ".format("empty"))


                #### indexes for DI excel cells management
                k = 80*j      #i con j
                l = 40*i      #k con l


                contvalueX = i + 1  #con zero da errore allora +1
                contvalueY = j + 1  #con zero da errore allora +1

                self.txt1 = tkinter.Text(self.root, width='10', height='1')


                #Reading excel cells file

                if (wsH.Cells(contvalueX, contvalueY ).Value != None):

                    self.txt1.insert('1.0', wsH.Cells(contvalueX, contvalueY ).Value)#ws.Cells(1,i).Value
                    self.txt1.tag_add("start", "1.0", "1.13")
                    if (contvalueY == 1 ):  
                        self.txt1.tag_config("start", background="white", foreground="red")
                    #self.txt1.tag_configure("red", foreground="red")
                    #self.txt1.highlight_pattern("word", "red")
                    #self.txt1 = tkinter.Text(self.root, width='10', height='1', text = ws.Cells(1,i).Value)
                    self.txt1.place(x=85+k, y=80+l)  #5 + 80
                    print("if")

                else:  #None case
                    print("else")
                    self.txt1.insert('1.0', "")
                    self.txt1.place(x=85+k, y=80+l)
                    if (contvalueY == 1 ):  
                        self.txt1.tag_config("start", background="white", foreground="red")




        wbH.Close()
        xl.Quit()


if __name__ == '__main__':
    root = tkinter.Tk()
    w, h = root.winfo_screenwidth(), root.winfo_screenheight()
    root.geometry("%dx%d+0+0" % (w, h))
    applicazione(root)
    root.mainloop()

The application runned:

application image without scrollbar

I read data from an excel file (lettura function) but i would like to add an horizontal and a vertical scrollbar i read first of all this:

Adding a scrollbar to a group of widgets in Tkinter

but use "grid" that i do not use and i'm not able to associate my double "for" "Text" to the vertical scroll bar (Lettura function)

The following code is edited with the scrollbar but does not work:

import tkinter as tk

from win32com.client import Dispatch
from tkinter import *
#from tkinter import ttk
import tkinter

class Example(tk.Frame):
    def __init__(self, root):

        tk.Frame.__init__(self, root)
        root.title('Controllo dati per fatturazione elettronica - Manticle - Smith & Nephew Italia')
        #tk.Frame(root, width=100, height=450).pack()



        self.canvas = tk.Canvas(root,  borderwidth=0, background="#C0C0C0")
        self.frame = tk.Frame(self.canvas, background="#ffffff")
        self.vsb = tk.Scrollbar(root, orient="vertical", command=self.canvas.yview)
        self.canvas.configure(yscrollcommand=self.vsb.set)

        self.vsb.pack(side="right", fill="y")
        self.canvas.pack(side="left", fill="both", expand=True)
        self.canvas.create_window((4,4), window=self.frame, anchor="nw", 
                                  tags="self.frame")

        self.frame.bind("<Configure>", self.onFrameConfigure)


        self.titoli_BFT = ["Num_Doc", "Cod_Art", "Unita Misura", "Tot_Prod", "Quant_Prod", "Perc_IVA_Prod", "Tot_IVA_Prod",
                           "Linea_Prod", "Sconto", "Perc_Sconto", "Tipo_Sconto", "Cod_Art2", "Desc_Art"]

        self.titoli_HFT = ["Dest_Cod_FIS_P_Iva", "Cod_Cli", "Dest_RagSoc1", "Dest_RagSoc2",
                           "Dest_Indirizzo", "Dest_CAP", "Dest_Localita", "Dest_Provincia", "Cli_Cod_Fis_P_Iva",
                            "Cod_Dest", "Cli_RagSoc1", "Cli_RagSoc2", "Cli_Indirizzo", "Cli_CAP",
                           "Cli_Localita", "Cli_Provincia", "Tipo_Doc", "pre_Num_Doc", "Num_Doc",
                            "Data_Doc", "Vs_Rif", "Data_Rif", "Blank", "Blank2", "CPT", "Scad_Pagamento",
                           "Descr", "Num_Ord", "Tot_Imp", "Tot_IVA", "Tot_Doc", "Nazione", "IPA", "Reg_Fiscale"]


        #self.inizializza_widgets()
        self.populate()
        self.lettura()




    def inizializza_widgets(self):
        #label title

        self.lblins=tk.Label(root, text="Controllo dati per fatturazione elettronica", font=("Helvetica", 12))
        self.lblins.place(x=10, y=10)



        for i in range (0,len(self.titoli_HFT)):
            j = 80*i
            self.lblnome=tk.Label(root, text= self.titoli_HFT[i], font=("Helvetica", 8))
            self.lblnome.place(x=85+j, y=50)


        #965 560
        tk.Button(root, text='Inserisci', width='10').place(x=645, y=590)
        #pulsante lettura
        tk.Button(root, text='Modifica', width='10').place(x=725, y=590)

        tk.Button(root, text='Indietro', width='10').place(x=805, y=590)

        tk.Button(root, text='Avanti', width='10').place(x=885, y=590)


    def lettura(self):
            xl= Dispatch("Excel.Application")
            xl.Visible = True

            wbH = xl.Workbooks.Open(r'C:\Users\\Marco\\LAVORO\\Smith&Nephew\\appRonca\\fonte\\HFT_SAP_2.csv')
            print("wbH")

            wsH=wbH.WorkSheets(1) # get a reference to the first sheet



            cont = 0

            MAX = 9  #13 lunghezza visibile senza barra navigatrice del numero di righe nella finestra 13
            cont = 0







            for i in range(0, MAX):
                for j in range(0,len(self.titoli_HFT)):
                    print("for for")
                    cont = cont + 1

                    print("cont")
                    print(cont)

                    #### INDEXES
                    k = 80*j      #i con j
                    l = 40*i      #k con l


                    contvalueX = i + 1  #con zero da errore allora +1
                    contvalueY = j + 1  #con zero da errore allora +1

                    self.txt1 = tk.Text(root, width='10', height='1')




                    #Lettura celle del file HFT

                    if (wsH.Cells(contvalueX, contvalueY ).Value != None):

                        self.txt1.insert('1.0', wsH.Cells(contvalueX, contvalueY ).Value)#ws.Cells(1,i).Value
                        self.txt1.tag_add("start", "1.0", "1.13")
                        if (contvalueY == 1 ):  
                            self.txt1.tag_config("start", background="white", foreground="red")

                        self.txt1.place(x=85+k, y=80+l)  #5 + 80
                        print("if")

                    else: #None case
                        print("else")
                        self.txt1.insert('1.0', "")
                        self.txt1.place(x=85+k, y=80+l)
                        if (contvalueY == 1 ):  #### qui si richiama la funziona regole con tutte le regole
                            self.txt1.tag_config("start", background="white", foreground="red")

            wbH.Close()
            xl.Quit()



    def onFrameConfigure(self, event):
        '''Reset the scroll region to encompass the inner frame'''
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))

if __name__ == "__main__":
    root=tk.Tk()
    Example(root).pack(side="top", fill="both", expand=True)
    root.mainloop()

and this: How to add a scrollbar to a window with tkinter? that is not organise like a class.

how can i implement the 2 scrollbars?

UPDATE

new version:

from win32com.client import Dispatch
from tkinter import *
from tkinter import ttk
import tkinter


class applicazione:


    def __init__(self, root):
        self.root = root

        # Top-level frame

        self.frame = ttk.Frame(self.root, relief="sunken")

        # Canvas creation with double scrollbar
        hscrollbar = ttk.Scrollbar(self.frame, orient = tkinter.HORIZONTAL)
        vscrollbar = ttk.Scrollbar(self.frame, orient = tkinter.VERTICAL)
        self.canvas = tkinter.Canvas(self.frame, bd=0, highlightthickness=0, yscrollcommand = vscrollbar.set, xscrollcommand = hscrollbar.set)
        vscrollbar.config(command = self.canvas.yview)
        hscrollbar.config(command = self.canvas.xview)


        # Add controls here
        self.subframe = ttk.Frame(self.canvas)

        #Packing everything
        self.subframe.pack(padx   = 15, pady   = 15, fill = tkinter.BOTH, expand = tkinter.TRUE)
        hscrollbar.pack( fill=tkinter.X, side=tkinter.BOTTOM, expand=tkinter.FALSE)
        vscrollbar.pack( fill=tkinter.Y, side=tkinter.RIGHT, expand=tkinter.FALSE)
        self.canvas.pack(side = tkinter.LEFT, padx  = 5, pady   = 5, fill = tkinter.BOTH, expand= tkinter.TRUE)
        self.frame.pack( padx   = 5, pady   = 5, expand = True, fill = tkinter.BOTH)


        self.canvas.create_window(0,0, window = self.subframe)
        self.root.update_idletasks() # update geometry
        self.canvas.config(scrollregion = self.canvas.bbox("all"))
        self.canvas.xview_moveto(0) 
        self.canvas.yview_moveto(0)


        self.root.title('Controllo dati per fatturazione elettronica - Manticle - Smith & Nephew Italia')
        ttk.Frame(self.root, width=300, height=250).pack()


        #### Titles
        self.titoli_HFT = ["Dest_Cod_FIS_P_Iva", "Cod_Cli", "Dest_RagSoc1", "Dest_RagSoc2",
                           "Dest_Indirizzo", "Dest_CAP", "Dest_Localita", "Dest_Provincia", "Cli_Cod_Fis_P_Iva",
                            "Cod_Dest", "Cli_RagSoc1", "Cli_RagSoc2", "Cli_Indirizzo", "Cli_CAP",
                           "Cli_Localita", "Cli_Provincia", "Tipo_Doc", "pre_Num_Doc", "Num_Doc",
                            "Data_Doc", "Vs_Rif", "Data_Rif", "Blank", "Blank2", "CPT", "Scad_Pagamento",
                           "Descr", "Num_Ord", "Tot_Imp", "Tot_IVA", "Tot_Doc", "Nazione", "IPA", "Reg_Fiscale"]



        self.inizializza_widgets()


    def inizializza_widgets(self):

        self.lblins=tkinter.Label(self.root, text="Controllo dati per fatturazione elettronica", font=("Helvetica", 12))
        self.lblins.place(x=10, y=10)

        for i in range (0,len(self.titoli_HFT)):
            j = 80*i
            self.lblnome=tkinter.Label(self.root, text= self.titoli_HFT[i], font=("Helvetica", 8))
            self.lblnome.place(x=85+j, y=50)

        ttk.Button(self.root, text='Inserisci', width='10').place(x=645, y=590)

        ttk.Button(self.root, text='Modifica', width='10').place(x=725, y=590)

        ttk.Button(self.root,  text='Indietro', width='10').place(x=805, y=590)

        ttk.Button(self.root,  text='Avanti', width='10').place(x=885, y=590)



if __name__ == '__main__':
    root = tkinter.Tk()
    root.title( "Double scrollbar with tkinter" )
    w, h = root.winfo_screenwidth(), root.winfo_screenheight()
    root.geometry("%dx%d+0+0" % (w, h))
    applicazione(root)
    root.mainloop()
Community
  • 1
  • 1
user3798245
  • 51
  • 1
  • 10
  • your code example doesn't run (is missing a `populate` function. Also, it doesn't even attempt to add a horizontal scrollbar. You say it "doesn't work" but what does that mean? You're not even attempting to add a horizontal scrollbar. What are you having trouble with? Making the scrollbar visible? Making it horizontal instead of vertical? – Bryan Oakley Jul 21 '15 at 10:36
  • My issues are with lettura function and vertical scrollbar that i attempted to add in the second piece of code. I need horizontal and vertical scrollbar but i do not even to make visible the vertical scrollbar – user3798245 Jul 22 '15 at 15:39
  • Part of the problem seems to be that you're putting a frame inside the canvas, but you aren't putting anything inside the frame. So, the frame will have a size of 1x1. I can only guess if that's the only problem, since the code you presented doesn't run. – Bryan Oakley Jul 22 '15 at 16:31

3 Answers3

2

I've also struggled with creating a double scrollbar window. Here is an implementation using pack layout manager (you should be able to tailor it for a grid layout) :

import tkinter as tk
from tkinter import ttk

# Top-level frame
root = tk.Tk()
root.title( "Double scrollbar with tkinter" )
root.minsize(width = 600, height = 600)
frame = ttk.Frame(root, relief="sunken")

# Canvas creation with double scrollbar
hscrollbar = ttk.Scrollbar(frame, orient = tk.HORIZONTAL)
vscrollbar = ttk.Scrollbar(frame, orient = tk.VERTICAL)
sizegrip = ttk.Sizegrip(frame)
canvas = tk.Canvas(frame, bd=0, highlightthickness=0, yscrollcommand = vscrollbar.set, xscrollcommand = hscrollbar.set)
vscrollbar.config(command = canvas.yview)
hscrollbar.config(command = canvas.xview)


# Add controls here
subframe = ttk.Frame(canvas)

#Packing everything
subframe.pack(padx   = 15, pady   = 15, fill = tk.BOTH, expand = tk.TRUE)
hscrollbar.pack( fill=tk.X, side=tk.BOTTOM, expand=tk.FALSE)
vscrollbar.pack( fill=tk.Y, side=tk.RIGHT, expand=tk.FALSE)
sizegrip.pack(in_ = hscrollbar, side = tk.BOTTOM, anchor = "se")
canvas.pack(side = tk.LEFT, padx  = 5, pady   = 5, fill = tk.BOTH, expand= tk.TRUE)
frame.pack( padx   = 5, pady   = 5, expand = True, fill = tk.BOTH)


canvas.create_window(0,0, window = subframe)
root.update_idletasks() # update geometry
canvas.config(scrollregion = canvas.bbox("all"))
canvas.xview_moveto(0) 
canvas.yview_moveto(0)


# launch the GUI
root.mainloop()

(Tested with Python 3.4).

Exemples : enter image description here enter image description here

It's not perfect, since it lacks the small block on the bottom right corner.

UPDATE 1 : Added Sizegrip to get the bottom right resizing corner

UPDATE 2 : Added working solution to OP's updated code

from win32com.client import Dispatch
from tkinter import *
from tkinter import ttk
import tkinter


class applicazione(object):


    def __init__(self, root):
        self.root = root

        # Top-level frame
        self.root.title('Controllo dati per fatturazione elettronica - Manticle - Smith & Nephew Italia')

        self.frame = ttk.Frame(self.root, width=300, height=250)

        # Canvas creation with double scrollbar
        hscrollbar = ttk.Scrollbar(self.frame, orient = tkinter.HORIZONTAL)
        vscrollbar = ttk.Scrollbar(self.frame, orient = tkinter.VERTICAL)
        sizegrip = ttk.Sizegrip(self.frame)
        self.canvas = tkinter.Canvas(self.frame, bd=0, highlightthickness=0, yscrollcommand = vscrollbar.set, xscrollcommand = hscrollbar.set)
        vscrollbar.config(command = self.canvas.yview)
        hscrollbar.config(command = self.canvas.xview)


        # Add controls here
        self.subframe = ttk.Frame(self.canvas)        


        #### Titles
        self.titoli_HFT = ["Dest_Cod_FIS_P_Iva", "Cod_Cli", "Dest_RagSoc1", "Dest_RagSoc2",
                           "Dest_Indirizzo", "Dest_CAP", "Dest_Localita", "Dest_Provincia", "Cli_Cod_Fis_P_Iva",
                            "Cod_Dest", "Cli_RagSoc1", "Cli_RagSoc2", "Cli_Indirizzo", "Cli_CAP",
                           "Cli_Localita", "Cli_Provincia", "Tipo_Doc", "pre_Num_Doc", "Num_Doc",
                            "Data_Doc", "Vs_Rif", "Data_Rif", "Blank", "Blank2", "CPT", "Scad_Pagamento",
                           "Descr", "Num_Ord", "Tot_Imp", "Tot_IVA", "Tot_Doc", "Nazione", "IPA", "Reg_Fiscale"]



        self.inizializza_widgets()

        #Packing everything
        self.subframe.pack(fill = tkinter.BOTH, expand = tkinter.TRUE)
        hscrollbar.pack( fill=tkinter.X, side=tkinter.BOTTOM, expand=tkinter.FALSE)
        vscrollbar.pack( fill=tkinter.Y, side=tkinter.RIGHT, expand=tkinter.FALSE)
        sizegrip.pack(in_= hscrollbar, side = BOTTOM, anchor = "se")
        self.canvas.pack(side = tkinter.LEFT, padx  = 5, pady  = 5, fill = tkinter.BOTH, expand= tkinter.TRUE)
        self.frame.pack( padx   = 5, pady  = 5, expand = True, fill = tkinter.BOTH)


        self.canvas.create_window(0,0, window = self.subframe)
        self.root.update_idletasks() # update geometry
        self.canvas.config(scrollregion = self.canvas.bbox("all"))
        self.canvas.xview_moveto(0) 
        self.canvas.yview_moveto(0)    


    def inizializza_widgets(self):

        self.LabelFrame = ttk.Frame(self.subframe)
        self.lblins = tkinter.Label(self.LabelFrame, text="Controllo dati per fatturazione elettronica", font=("Helvetica", 12))
        self.lblins.pack()

        for i in range (0,len(self.titoli_HFT)):
            j = 80*i
            self.lblnome=tkinter.Label(self.LabelFrame, text= self.titoli_HFT[i], font=("Helvetica", 8))
            self.lblnome.pack(side = LEFT)#place(x=85+j, y=50)

        self.ContentFrame = ttk.Frame(self.subframe, width = 600, height = 600)

        self.ButtonsFrame = ttk.Frame(self.subframe)
        ttk.Frame(self.ButtonsFrame).pack(side=LEFT, fill = X, expand=TRUE)
        ttk.Button(self.ButtonsFrame, text='Inserisci', width='10').pack(side = LEFT)
        ttk.Button(self.ButtonsFrame, text='Modifica', width='10').pack(side = LEFT)
        ttk.Button(self.ButtonsFrame,  text='Indietro', width='10').pack(side = LEFT)
        ttk.Button(self.ButtonsFrame,  text='Avanti', width='10').pack(side = LEFT)
        ttk.Frame(self.ButtonsFrame).pack(side=RIGHT, fill = X, expand=TRUE)

        self.LabelFrame.pack(side = TOP, fill = X, expand=TRUE)
        self.ContentFrame.pack(fill = BOTH, expand = TRUE)
        self.ButtonsFrame.pack(side = BOTTOM, fill = X, expand = TRUE)



if __name__ == '__main__':
    root = tkinter.Tk()
    root.title( "Double scrollbar with tkinter" )
    w, h = root.winfo_screenwidth(), root.winfo_screenheight()
    root.geometry("%dx%d+0+0" % (0.99*w, 0.9*h))
    applicazione(root)


    root.mainloop()

enter image description here

lucasg
  • 10,734
  • 4
  • 35
  • 57
  • I tried to implement your versione (i added a new version below UPDATE, at this line: for i in range (0,len(self.titoli_HFT)): self.lblnome=tkinter.Label(self.root, text= self.titoli_HFT[i], font=("Helvetica", 8)) if i put self.root, self.frame, self.subframe, self.canvas never view an active scrollbar! – user3798245 Jul 23 '15 at 09:02
  • The "small block in the corner" is provided by ttk.Sizegrip. – patthoyts Jul 23 '15 at 09:23
  • @patthoyts : thanks for the sizegrip tip. I didn't know that. – lucasg Jul 24 '15 at 13:30
  • @user3798245 : there is a problem with your updated code. Tkinter has several layout managers : pack, place and grip. It is recommended to stick with only one. My solution use the packing layout whereas patthoyts use the grid one, and you use the place. I added a solution with the packing manager – lucasg Jul 24 '15 at 13:32
1

Just to expand on the answer by @georgesl and demonstrate the use of the ttk sizegrip and also to show that grid works nicely for this kind of task, here is a short example showing a text widget with 2 scrollbars and the sizegrip in the corner.

# Demonstrate text widget with two scrollbars and the sizegrip.
import tkinter as tk
import tkinter.ttk as ttk

root = tk.Tk()
text = tk.Text(root)
vs = ttk.Scrollbar(root, orient="vertical")
hs = ttk.Scrollbar(root, orient="horizontal")
sizegrip = ttk.Sizegrip(root)

# hook up the scrollbars to the text widget
text.configure(yscrollcommand=vs.set, xscrollcommand=hs.set, wrap="none")
vs.configure(command=text.yview)
hs.configure(command=text.xview)

# grid everything on-screen
text.grid(row=0,column=0,sticky="news")
vs.grid(row=0,column=1,sticky="ns")
hs.grid(row=1,column=0,sticky="news")
sizegrip.grid(row=1,column=1,sticky="news")
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)

def fill():
    for n in range(30):
        text.insert("end", 'hello ' * 20, "", "\n")
root.after(20, fill)
root.mainloop()
patthoyts
  • 32,320
  • 3
  • 62
  • 93
0

The process to add both a horizontal and vertical scrollbar to a collection of widgets is precisely the same as the solution provided in this answer: https://stackoverflow.com/a/3092341/7432. That answer shows only a vertical scrollbar, but adding a horizontal one is just a matter of a couple lines of code.

The solution is very straight-forward:

  • add widgets to a frame using whatever method you want
  • add the frame to a canvas using the create_window method of the canvas
  • add scrollbars to the canvas in the usual way
  • set the scrollregion attribute of the canvas to be big enough to incude the entire frame that was added
    • do this whenever you add or remove widgets from the frame
    • you might also need to do this whenever the canvas changes size
Community
  • 1
  • 1
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685