如何使用滚动条功能将标签装入Tkinter框架和画布?

时间:2017-03-27 23:16:05

标签: python tkinter tkinter-canvas

我正在尝试创建一个可以检查的字母列表,但是当列表离开窗口时我不知道如何让滚动条工作。我已经读过你需要将标签放入框架然后放入画布,但这对我不起作用。

这是我的代码:

import Tkinter as tk

LARGE_FONT = ("Verdana", 12)
NORMAL_FONT = ("Verdana", 10)
SMALL_FONT = ("Verdana", 8)

number_of_rows = 20

def popupmsg(msg):
    popup = tk.Tk()
    popup.wm_title("!")
    label = tk.Label(popup, text=msg, font=NORMAL_FONT)
    label.pack(side="top", fill="x", pady=10)
    B1 = tk.Button(popup, text="Okay", command=popup.destroy)
    B1.pack()
    popup.mainloop()



class Window(tk.Tk):

    def __init__(self, *args, **kwargs):
    tk.Tk.__init__(self, *args, **kwargs)
    master_frame = tk.Frame(self)
    container = tk.Canvas(master_frame, height=300, width=720, scrollregion=(0,0,300,720))

    master_frame.pack(side="top", fill="both", expand=True)

    vbar = tk.Scrollbar(container,orient="vertical")
    vbar.grid(column=1, sticky="ns")
    vbar.config(command=container.yview)

    container.grid_rowconfigure(-0, weight=1)
    container.grid_columnconfigure(-0, weight=1)

    container.config(yscrollcommand=vbar.set)
    container.pack(side="top", fill="both", expand=True)
    #container.create_window(0,0,window=master_frame, anchor='nw')

    child_to_container_frame = tk.Frame(container)
    child_to_container_frame.grid_rowconfigure(-0, weight=1)
    child_to_container_frame.grid_columnconfigure(-0, weight=1)


    self.frames = {}

    menubar = tk.Menu(master_frame)
    filemenu = tk.Menu(menubar, tearoff=0)
    filemenu.add_command(label="Help", command = lambda: popupmsg("Not supported yet"))
    filemenu.add_separator()
    filemenu.add_command(label="Exit", command=quit)
    menubar.add_cascade(label="File", menu=filemenu)
    optionmenu = tk.Menu(menubar, tearoff=0)
    optionmenu.add_command(label="Option #1", command = lambda: popupmsg("You clicked option #1"))
    optionmenu.add_command(label="Option #2", command = lambda: popupmsg("You clicked option #2"))
    optionmenu.add_command(label="Option #3", command = lambda: popupmsg("You clicked option #3"))
    menubar.add_cascade(label="Options", menu=optionmenu)
    menubar.add_command(label="Start", command = lambda: popupmsg("Starting Scan"))

    tk.Tk.config(self, menu=menubar)

    frame = StartPage(child_to_container_frame, self)
    self.frames[StartPage] = frame
    frame.grid(row=0, column=0, sticky="nsew")
    self.show_frame(StartPage)



    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()


class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.PlaceLabels()

    def PlaceLabels(self):
        self.row = []
        self.checkboxrow = []
        self.text_in_row = []
        self.states = []
        letter = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T"]
        for i in range(number_of_rows):
            self.states.append(tk.IntVar())
            self.row.append(tk.Label(self, bg="white", pady=5, font=(None, 1), height=20, width=720))
            self.row[i].grid(row=i, column=0, sticky="ew", padx=3, pady=5)
            self.checkboxrow.append(tk.Checkbutton(self, bg="white", variable=self.states[i], command= lambda: self.DarkenLabel()))
            self.checkboxrow[i].grid(row=i, column=0, sticky="w", padx=10)
            self.text_in_row.append(tk.Label(self, bg="white", text=letter[i]))
            self.text_in_row[i].grid(row=i, column=0)

    def DarkenLabel(self):
        for i in range(len(self.checkboxrow)):
            if self.states[i].get() == 1:
                self.row[i].config(bg="gray")
                self.checkboxrow[i].config(bg="gray")
                self.text_in_row[i].config(bg="gray")
            else:
                self.row[i].config(bg="white")
                self.checkboxrow[i].config(bg="white")
                self.text_in_row[i].config(bg="white")                


app = Window()
app.geometry('733x500')
app.mainloop()

我认为问题出在Windows类的开头,但我不知道。

我试过了: container.pack(side="top", fill="both", expand=True)container.create_window(0,0,window=master_frame, anchor='nw') 但两者都不适合我。

有什么建议吗? 谢谢你的帮助

1 个答案:

答案 0 :(得分:0)

我从他的评论中听取了Bryan Oakley的建议,这确实帮助我解决了这个问题。这是我的代码,只有简单的骨头:

import Tkinter as tk


class Window(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        master_frame = tk.Frame(self)
        master_frame.pack(side="top", fill="both", expand=True)

        vbar = tk.Scrollbar(master_frame)
        vbar.pack(side='right',fill="y")

        container = tk.Canvas(master_frame, height=300, width=720, scrollregion=(0,0,300,720))                
        container.pack(side="top", fill="both", expand=True)

        child_to_container_frame = tk.Frame(container)
        container.create_window(0,0,window=child_to_container_frame, anchor='nw')        

        vbar.config(command=container.yview)
        container.config(yscrollcommand=vbar.set, scrollregion=(0,0,1000,1500))

        self.frames = {}
        frame = StartPage(child_to_container_frame, self)
        self.frames[StartPage] = frame
        frame.grid(row=0, column=0, sticky="nsew")
        self.show_frame(StartPage)

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()


class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.row = []
        self.row.append(tk.Label(self, bg="white", pady=5, font=(None, 1), height=20, width=720))
        self.row[0].grid(row=0, column=0, sticky="ew", padx=3, pady=5)        


app = Window()
app.geometry('733x500')
app.mainloop()