tkinter: simple scrollable text

19,681

Answer

Use a readonly 'entry' widget - it looks the same as a label, and doesn't need to be put in a canvas.

Code

import tkinter as tk
from tkinter import ttk

root = tk.Tk()

mytext = tk.StringVar(value='test ' * 30)

myframe = ttk.Frame(root)
myentry = ttk.Entry(myframe, textvariable=mytext, state='readonly')
myscroll = ttk.Scrollbar(myframe, orient='horizontal', command=myentry.xview)
myentry.config(xscrollcommand=myscroll.set)

myframe.grid()
myentry.grid(row=1, sticky='ew')
myscroll.grid(row=2, sticky='ew')

root.mainloop()

Result

enter image description here

Share:
19,681
Jake Levi
Author by

Jake Levi

Updated on June 04, 2022

Comments

  • Jake Levi
    Jake Levi almost 2 years

    Question

    I'm trying to make a 'ttk Label' which a) is 20 pixels high by 300 pixels wide, b) is scrollable (in this case horizontally), and c) uses the simplest code possible within reason (except for the fact that the text and scrollbar are both within a frame*). I've found stackoverflow to be helpful in describing the processes I need to go through (put the label in a frame, put the frame in a canvas, put the scroll bar next to or underneath the canvas and 'bind' them together somehow), but despite looking at a fair few docs and stackoverflow questions, I can't figure out why my code isn't working properly. Please could someone a) update the code so that it satisfies the conditions above, and b) let me know if I've done anything unnecessary? Thanks

    *the frame will be going in a project of mine, with text that is relevant

    Current code

    import tkinter as tk
    from tkinter import ttk
    
    root = tk.Tk()
    
    myframe_outer = ttk.Frame(root)
    mycanvas = tk.Canvas(myframe_outer, height=20, width=300)
    myframe_inner = ttk.Frame(mycanvas)
    myscroll = ttk.Scrollbar(myframe_outer, orient='horizontal', command=mycanvas.xview)
    mycanvas.configure(xscrollcommand=myscroll.set)
    
    myframe_outer.grid()
    mycanvas.grid(row=1, sticky='nesw')
    myscroll.grid(row=2, sticky='ew')
    mycanvas.create_window(0, 0, window=myframe_inner, anchor='nw')
    ttk.Label(myframe_inner, text='test ' * 30).grid(sticky='w')
    
    root.mainloop()
    

    Edit:

    Current result

    enter image description here