我创建了一个多页程序(在Mac上使用Python 2.7和Tkinter),页面之间有导航按钮。我希望能够在某些页面上使用Scrollbar,但是当我为每个页面添加Scrollbar代码时,只有添加了滚动条代码的最后一页是可滚动的。滚动条效果很好(我理解如何制作),但似乎一次只能有一个页面可以有一个工作滚动条。为什么?几年前这里(Python Tkinter scrollbar in multiple tabs)提出了这个确切的问题(差不多),但从未得到回答。我也尝试将滚动条代码放入“主窗口”和“创建新文件”类代码,但是时髦的事情发生了。这是我正在尝试做的基本版本:
from Tkinter import *
def quit(): #quits the program
master.destroy()
class FirstPage(Frame):
def __init__(self, *args, **kwargs):
Frame.__init__(self, *args, **kwargs)
#creating vertical and horizontal scrollbars
self.canvas = Canvas(self, background = "#ffffff",
highlightcolor = "white")
self.canvas.pack(side = "left", fill = "both", anchor = "center",
expand = True)
self.vscrollbar = Scrollbar(self, orient = "vertical",
command = self.canvas.yview)
self.vscrollbar.pack(side = "right", fill = "y")
self.canvas.configure(yscrollcommand = self.vscrollbar.set)
self.hscrollbar = Scrollbar(self, orient = "horizontal",
command = self.canvas.xview)
self.hscrollbar.pack(side = "bottom", fill = "x")
self.canvas.configure(xscrollcommand = self.hscrollbar.set)
self.container = Frame(self.canvas, highlightcolor = "white")
self.canvas.create_window(0, 0, window = self.container,
anchor = "center")
self.container.bind("<Configure>", self.onFrameConfigure)
self.canvas.bind_all("<MouseWheel>", self.on_vertical)
self.canvas.bind_all("<Shift-MouseWheel>", self.on_horizontal)
self.label = Label(self.container, text = "Welcome!")
self.label.pack(side = "top", fill = "both", expand = False)
def onFrameConfigure(self, event):
#Reset the scroll region to encompass the inner frame
self.canvas.configure(scrollregion = self.canvas.bbox("all"))
def on_vertical(self, event):
self.canvas.yview_scroll(-1 * event.delta, 'units')
#lets the user use the mouse/trackpad to vertically scroll
def on_horizontal(self, event):
self.canvas.xview_scroll(-1 * event.delta, 'units')
#lets the user use the shift-mouse/trackpad to horizontally scroll
class SecondPage(Frame):
def __init__(self, *args, **kwargs):
Frame.__init__(self, *args, **kwargs)
#creating vertical and horizontal scrollbars
self.canvas = Canvas(self, background = "#ffffff",
highlightcolor = "white")
self.canvas.pack(side = "left", fill = "both", anchor = "center",
expand = True)
self.vscrollbar = Scrollbar(self, orient = "vertical",
command = self.canvas.yview)
self.vscrollbar.pack(side = "right", fill = "y")
self.canvas.configure(yscrollcommand = self.vscrollbar.set)
self.hscrollbar = Scrollbar(self, orient = "horizontal",
command = self.canvas.xview)
self.hscrollbar.pack(side = "bottom", fill = "x")
self.canvas.configure(xscrollcommand = self.hscrollbar.set)
self.container = Frame(self.canvas, highlightcolor = "white")
self.canvas.create_window(0, 0, window = self.container,
anchor = "center")
self.container.bind("<Configure>", self.onFrameConfigure)
self.canvas.bind_all("<MouseWheel>", self.on_vertical)
self.canvas.bind_all("<Shift-MouseWheel>", self.on_horizontal)
self.label = Label(self.container, text = "Hello World!")
self.label.pack(side = "top", fill = "both", expand = False)
def onFrameConfigure(self, event):
#Reset the scroll region to encompass the inner frame
self.canvas.configure(scrollregion = self.canvas.bbox("all"))
def on_vertical(self, event):
self.canvas.yview_scroll(-1 * event.delta, 'units')
#lets the user use the mouse/trackpad to vertically scroll
def on_horizontal(self, event):
self.canvas.xview_scroll(-1 * event.delta, 'units')
#lets the user use the shift-mouse/trackpad to horizontally scroll
class ThirdPage(Frame):
def __init__(self, *args, **kwargs):
Frame.__init__(self, *args, **kwargs)
#creating vertical and horizontal scrollbars
self.canvas = Canvas(self, background = "#ffffff",
highlightcolor = "white")
self.canvas.pack(side = "left", fill = "both", anchor = "center",
expand = True)
self.vscrollbar = Scrollbar(self, orient = "vertical",
command = self.canvas.yview)
self.vscrollbar.pack(side = "right", fill = "y")
self.canvas.configure(yscrollcommand = self.vscrollbar.set)
self.hscrollbar = Scrollbar(self, orient = "horizontal",
command = self.canvas.xview)
self.hscrollbar.pack(side = "bottom", fill = "x")
self.canvas.configure(xscrollcommand = self.hscrollbar.set)
self.container = Frame(self.canvas, highlightcolor = "white")
self.canvas.create_window(0, 0, window = self.container,
anchor = "center")
self.container.bind("<Configure>", self.onFrameConfigure)
self.canvas.bind_all("<MouseWheel>", self.on_vertical)
self.canvas.bind_all("<Shift-MouseWheel>", self.on_horizontal)
self.label = Label(self.container, text = "Hello World 2.0!")
self.label.pack(side = "top", fill = "both", expand = False)
def onFrameConfigure(self, event):
#Reset the scroll region to encompass the inner frame
self.canvas.configure(scrollregion = self.canvas.bbox("all"))
def on_vertical(self, event):
self.canvas.yview_scroll(-1 * event.delta, 'units')
#lets the user use the mouse/trackpad to vertically scroll
def on_horizontal(self, event):
self.canvas.xview_scroll(-1 * event.delta, 'units')
#lets the user use the shift-mouse/trackpad to horizontally scroll
class CreateNewFile(Frame):
def __init__(self, *args, **kwargs):
Frame.__init__(self, *args, **kwargs)
""" If the scrollbar code goes here (and container is deleted then
replaced with self.container), then the buttonframe gets pushed to
the bottom, and the two buttons do not work (I cannot see the
pages they create). The scrollbar also doesn't work.
"""
#the pages the buttons will navigate to
secondpage = SecondPage(self)
thirdpage = ThirdPage(self)
#creating the navigation bar vs. the window
buttonframe = Frame(self)
buttonframe.pack(side = "top", fill = "x", anchor = "w", expand =
False)
#creating the window container
container = Frame(self)
container.pack(side = "top", fill = "both", expand = True)
#placing the pages in the container
secondpage.place(in_ = container, x = 0, y = 0, relwidth = 1,
relheight = 1)
thirdpage.place(in_ = container, x = 0, y = 0, relwidth = 1,
relheight = 1)
#placing the buttons in the navigation bar
secondpagebutton = Button(buttonframe, text = "2nd Page", command =
secondpage.lift)
secondpagebutton.pack(side = "left")
thirdpagebutton = Button(buttonframe, text = "3rd Page", command =
thirdpage.lift)
thirdpagebutton.pack(side = "left")
class MainWindow(Frame):
def __init__(self, *args, **kwargs):
Frame.__init__(self, *args, **kwargs)
#the pages the buttons will nagivate to
firstpage = FirstPage(self)
createnewfile = CreateNewFile(self)
""" If the scrollbar code goes here (and container is deleted then
replaced with self.container), then the buttonframe gets pushed to
the bottom, and the the createnewfilebutton does not work (I
cannot see the page it creates). The scrollbar also doesn't work.
"""
#creating the button navigation bar and the rest of the window so the
#buttons are always visible no matter which page you're on
buttonframe = Frame(self)
buttonframe.pack(side = "top", fill = "x", expand = False)
#creating the window container
container = Frame(self)
container.pack(side = "top", fill = "both", expand = True)
#placing the pages in the container
firstpage.place(in_ = container, x = 0, y = 0, relwidth = 1,
relheight = 1)
createnewfile.place(in_ = container, x = 0, y = 0, relwidth = 1,
relheight = 1)
#placing the buttons in the navigation bar
quitbutton = Button(buttonframe, text = "Quit", command = quit)
quitbutton.pack(side = "left") #this quits the whole program
createnewfilebutton = Button(buttonframe, text = "Create New File",
command = createnewfile.lift)
createnewfilebutton.pack(side = "left")
firstpage.lift()
if __name__ == "__main__":
master = Tk()
main = MainWindow(master)
main.pack(side = "top", fill = "both", expand = True)
main.master.title("Basic Example")
master.wm_geometry("600x500+0+0")
master.mainloop()
有没有办法让每个页面滚动,或者我是否需要放弃能够滚动每个页面上的多个小部件,只需滚动支持它的小部件(如文本小部件)?
答案 0 :(得分:0)
问题是self.canvas.bind_all
创建了一个全局绑定。首先将<MouseWheel>
绑定到第一个画布。然后,您覆盖该绑定并将其绑定到第二个。然后,您覆盖该绑定并将其绑定到第三个。
每次更改页面时都需要更改全局绑定,或者使用bind
而不是bind_all
直接将绑定添加到每个画布。您的第三个选择是使您的绑定足够智能,以滚动任何可见的画布。