简体   繁体   English

tkinter python 中带有网格的滚动条

[英]scrollbar with grid in tkinter python

Here is my code (so sorry if it's too long).这是我的代码(如果太长,请见谅)。 And I want to create 1 vertical scroll bar.我想创建 1 个垂直滚动条。 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.因为我有很多行,我把它放在滚动条中,所以我可以滚动查看 GUI 无法显示的行。 I tried with Scrollbar but it is only in 1 row.我尝试使用 Scrollbar,但它只有 1 行。 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()

You need to:你需要:

  • create a frame inside the canvas and put those labels and comboboxes into this frame在 canvas 内创建一个框架,并将这些标签和组合框放入此框架
  • update scrollregion of canvas when the frame is resized调整框架大小时更新scrollregion的滚动区域
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.请注意,我from tkinter import *更改为import tkinter as tk ,因为不建议使用通配符导入。

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 .我根据这个答案以及其他答案创建了一个滚动框架 class ,您可以在此处找到。

This class can be added to your window/frame with pack or grid.这个 class 可以通过包装或网格添加到您的窗口/框架中。 It also allows widgets to be added using pack or frame.它还允许使用包或框架添加小部件。

thank you very much @asw1668 .非常感谢@asw1668 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM