python-3.xtkintertkinter-text

How to make Text widget non resizable when changing a Text size by mouse wheel?


When I try to scroll text in Text widget mousehweel also resize widget itself. But I just need to resize text inside.

import tkinter as tk


def on_mouse_wheel(event):
    # Increase or decrease the font size based on mouse wheel rotation
    if event.delta > 0:
        current_font_size = int(text_widget['font'].split()[1])
        text_widget.config(font=("Arial", current_font_size + 2))
    else:
        current_font_size = int(text_widget['font'].split()[1])
        text_widget.config(font=("Arial", current_font_size - 2))


root = tk.Tk()

text_widget = tk.Text(root, font=("Arial", 12),
                      wrap=tk.NONE)  # Set wrap to NONE
text_widget.pack(expand=True,
                 fill='both')  # Make the Text widget fill the available space

# Add a horizontal scrollbar
scrollbar = tk.Scrollbar(root, orient='horizontal', command=text_widget.xview)
scrollbar.pack(side='bottom', fill='x')
text_widget['xscrollcommand'] = scrollbar.set

# Bind the mouse wheel event to the on_mouse_wheel function
text_widget.bind("<MouseWheel>", on_mouse_wheel)

root.mainloop()

Can someone help?


Solution

  • You can put the Text widget into a containing Frame, then set the dimensions of that frame how you want them and set pack_propagate(False) on the frame to prevent it from resizing as you change the font size.

    I also added text_widget.see('end') to your mousewheel callback so the end of the text is always in view as you update the font size.

    import tkinter as tk
    
    
    def on_mouse_wheel(event):
        # Increase or decrease the font size based on mouse wheel rotation
        if event.delta > 0:
            current_font_size = int(text_widget['font'].split()[1])
            text_widget.config(font=("Arial", current_font_size + 2))
        else:
            current_font_size = int(text_widget['font'].split()[1])
            text_widget.config(font=("Arial", current_font_size - 2))
        # make sure the end of the text is always visible on size updates
        text_widget.see('end')
    
    
    root = tk.Tk()
    # create a frame to contain the text box (set width and height as desired)
    container = tk.Frame(root, width=480, height=240)
    container.pack_propagate(False)  # prevent the frame from resizing
    container.pack(fill='both')
    # set the text_widget's parent to 'container' here instead of 'root'
    text_widget = tk.Text(container, font=("Arial", 12),
                          wrap=tk.NONE)  # Set wrap to NONE
    text_widget.pack(expand=True,
                     fill='both')  # Make the Text widget fill the available space
    
    # Add a horizontal scrollbar
    scrollbar = tk.Scrollbar(root, orient='horizontal', command=text_widget.xview)
    scrollbar.pack(side='bottom', fill='x')
    text_widget['xscrollcommand'] = scrollbar.set
    
    # Bind the mouse wheel event to the on_mouse_wheel function
    text_widget.bind("<MouseWheel>", on_mouse_wheel)
    
    root.mainloop()