0

Here is my code (so sorry if it's too long). And I want to create 1 vertical scroll bar. Because I have a lot of lines and I put it in a scrollbar so I can scroll to see the lines that the GUI can't show. I tried with Scrollbar but it is only in 1 row. Sorry my english is not good. Can someone help me?

from tkinter import *
from tkinter import ttk


class LabelAndCombobox:
    def __init__(self, tk_root, row, text_label, value_combobox):
        # self.row = row
        self.text_label = text_label
        self.value_combobox = value_combobox
        self.textvariable = StringVar()
        # label text for combobox
        self.label = ttk.Label(tk_root, text=self.text_label+" ", font=("Times New Roman", 10), relief=RAISED).grid(column=0, row=row, padx=10, pady=5, sticky=W)

        # combobox
        self.combobox = ttk.Combobox(tk_root, width=50, textvariable=self.textvariable, values=self.value_combobox, state='readonly')
        self.combobox.current(None)
        self.combobox.unbind_class("TCombobox", "<MouseWheel>")
        self.combobox.bind('<<ComboboxSelected>>', lambda event: self.changed(event))
        self.combobox.grid(column=1, row=row, sticky=W)

    def changed(self, event):
        print(self.combobox.get())


if __name__ == '__main__':
    a = ["Ăn uống", "Ăn uống > Ẩm thực", "Ăn uống > Ẩm thực > Ẩm thực Hàn Quốc", "Ăn uống > Ẩm thực > Ẩm thực Việt",
         "Ăn uống > Cafe/Nước giải khát", "Ăn uống > Cafe/Nước giải khát > Nước hoa quả", " sinh tố",
         "Ăn uống > Cafe/Nước giải khát > Trà sữa", "Ăn uống > Đồ uống", "Ăn uống > Đồ uống có cồn",
         "Ăn uống > Đồ uống có cồn > Bia", "Ăn uống > Đồ uống có cồn > Rượu", "Ăn uống > Món ăn > Ăn vặt",
         "Ăn uống > Món ăn > Bánh > Bánh Âu", "Ăn uống > Món ăn > Đặc sản", "Ăn uống > Món ăn > Pizza",
         "Ăn uống > Nhà hàng", "Ăn uống > Nhà hàng > Quán nhậu", "Công việc", "Công việc > Dịch vụ chăm sóc cá nhân",
         "Công việc > Dịch vụ chăm sóc cá nhân > Nhân viên thẩm mỹ viện", " spa", "Công việc > Giáo dục",
         "Công việc > Giáo dục > Giáo dục tiểu học", "Công việc > Khoa học > Khoa học kỹ thuật",
         "Công việc > Khoa học > Khoa học kỹ thuật > Trắc địa", "Công việc > Khoa học > Khoa học kỹ thuật > Xây dựng",
         "Công việc > Khoa học > Khoa học kỹ thuật > Xây dựng > Kiến trúc dân dụng",
         "Công việc > Khoa học > Khoa học kỹ thuật > Xây dựng > Kỹ sư xây dựng", "Công việc > Nghệ thuật biểu diễn"]

    b = ["Ăn uống", "Ăn uống > Ẩm thực", "Ăn uống > Ẩm thực > Ẩm thực Hàn Quốc", "Ăn uống > Ẩm thực > Ẩm thực Việt",
     "Ăn uống > Cafe/Nước giải khát", "Ăn uống > Cafe/Nước giải khát > Nước hoa quả, sinh tố"]        

    root = Tk()
    root.geometry("600x700")
    canvas = Canvas(root, height=700, width=600)

    ybar = Scrollbar(root, orient=VERTICAL, command=canvas.yview)
    ybar.grid()
    canvas.config(yscrollcommand=ybar.set)

    count = 1
    for i in a:
        # LabelAndCombobox(root, count, "check  "+str(count), b)
        LabelAndCombobox(root, count, i, b)
        count += 1

    canvas.grid(rowspan=len(a), columnspan=2)
    root.mainloop()
2
  • Try searching questions on "tkinter scrollable frame" in StackOverflow. Commented Jan 18, 2022 at 10:13
  • thanks for your answer. I have tried many ways. but it still doesn't work Commented Jan 19, 2022 at 2:13

3 Answers 3

1

You need to:

  • create a frame inside the canvas and put those labels and comboboxes into this frame
  • update scrollregion of canvas when the frame is resized
import tkinter as tk
from tkinter import ttk


class LabelAndCombobox:
    def __init__(self, tk_root, row, text_label, value_combobox):
        # self.row = row
        self.text_label = text_label
        self.value_combobox = value_combobox
        self.textvariable = tk.StringVar()
        # label text for combobox
        self.label = ttk.Label(tk_root, text=self.text_label+" ", font=("Times New Roman", 10), relief=tk.RAISED)
        self.label.grid(column=0, row=row, padx=10, pady=5, sticky=tk.W)

        # combobox
        self.combobox = ttk.Combobox(tk_root, width=50, textvariable=self.textvariable, values=self.value_combobox, state='readonly')
        self.combobox.current(None)
        self.combobox.unbind_class("TCombobox", "<MouseWheel>")
        self.combobox.bind('<<ComboboxSelected>>', lambda event: self.changed(event))
        self.combobox.grid(column=1, row=row, sticky=tk.W)

    def changed(self, event):
        print(self.combobox.get())


if __name__ == '__main__':
    a = ["Ăn uống", "Ăn uống > Ẩm thực", "Ăn uống > Ẩm thực > Ẩm thực Hàn Quốc", "Ăn uống > Ẩm thực > Ẩm thực Việt",
         "Ăn uống > Cafe/Nước giải khát", "Ăn uống > Cafe/Nước giải khát > Nước hoa quả", " sinh tố",
         "Ăn uống > Cafe/Nước giải khát > Trà sữa", "Ăn uống > Đồ uống", "Ăn uống > Đồ uống có cồn",
         "Ăn uống > Đồ uống có cồn > Bia", "Ăn uống > Đồ uống có cồn > Rượu", "Ăn uống > Món ăn > Ăn vặt",
         "Ăn uống > Món ăn > Bánh > Bánh Âu", "Ăn uống > Món ăn > Đặc sản", "Ăn uống > Món ăn > Pizza",
         "Ăn uống > Nhà hàng", "Ăn uống > Nhà hàng > Quán nhậu", "Công việc", "Công việc > Dịch vụ chăm sóc cá nhân",
         "Công việc > Dịch vụ chăm sóc cá nhân > Nhân viên thẩm mỹ viện", " spa", "Công việc > Giáo dục",
         "Công việc > Giáo dục > Giáo dục tiểu học", "Công việc > Khoa học > Khoa học kỹ thuật",
         "Công việc > Khoa học > Khoa học kỹ thuật > Trắc địa", "Công việc > Khoa học > Khoa học kỹ thuật > Xây dựng",
         "Công việc > Khoa học > Khoa học kỹ thuật > Xây dựng > Kiến trúc dân dụng",
         "Công việc > Khoa học > Khoa học kỹ thuật > Xây dựng > Kỹ sư xây dựng", "Công việc > Nghệ thuật biểu diễn"]

    b = ["Ăn uống", "Ăn uống > Ẩm thực", "Ăn uống > Ẩm thực > Ẩm thực Hàn Quốc", "Ăn uống > Ẩm thực > Ẩm thực Việt",
     "Ăn uống > Cafe/Nước giải khát", "Ăn uống > Cafe/Nước giải khát > Nước hoa quả, sinh tố"]        

    root = tk.Tk()
    #root.geometry("600x700")

    canvas = tk.Canvas(root, height=700, width=600)

    ybar = tk.Scrollbar(root, orient=tk.VERTICAL, command=canvas.yview)
    ybar.pack(side=tk.RIGHT, fill=tk.Y)
    canvas.config(yscrollcommand=ybar.set)

    # create a frame inside canvas for those labels and comboboxes
    frame = tk.Frame(canvas)
    canvas.create_window(0, 0, window=frame, anchor='nw')

    # update scrollregion of canvas when the frame is resized
    frame.bind('<Configure>', lambda e:canvas.config(scrollregion=canvas.bbox('all')))

    count = 1
    for i in a:
        # changed root to frame
        LabelAndCombobox(frame, count, i, b)
        count += 1

    canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)

    root.bind('<MouseWheel>', lambda e: canvas.yview_scroll(e.delta//-120, 'units'))

    root.mainloop()

Note that I have changed from tkinter import * to import tkinter as tk because wildcard import is not recommended.

Sign up to request clarification or add additional context in comments.

3 Comments

wow. Thank you very much. It worked. But is there a way to make it work with the mouse wheel as well?
@NguyenSon Answer updated.
Thank you. Sorry for not seeing your update. But it's okay I found the same solution. Thank you for your enthusiasm.
1

I found this solution to be most useful.

I have created a scrolled frame class based on this answer, as well as others, which you can find here.

This class can be added to your window/frame with pack or grid. It also allows widgets to be added using pack or frame.

1 Comment

i tried your ScrollFrame solution but when i scroll the mouse it immediately scrolls to the bottom. I'm trying to fix it. Anyway thanks for your very helpful solution.
0

thank you very much @acw1668. His solution worked for me. Besides i want to use it with mouse wheel. Below is my solution. Hope it's helpful for those who have the same problem

def on_mousewheel(event):
    canvas.yview_scroll(int(-1 * (event.delta / 120)), "units")

canvas.bind_all("<MouseWheel>", on_mousewheel)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.