首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在多个选项卡中使用滚动条Python Tkinter

在多个选项卡中使用滚动条Python Tkinter
EN

Stack Overflow用户
提问于 2018-05-28 07:34:03
回答 1查看 645关注 0票数 -1

我已经创建了一个多页面程序(在Mac上使用Python2.7和Tkinter ),页面之间有导航按钮。我希望能够在一些页面上使用Scrollbar,但当我为每个页面输入Scrollbar代码时,只有添加了scrollbar代码的最后一个页面是可滚动的。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()

有没有办法让每个页面滚动,或者我需要放弃在每个页面上滚动多个小部件的能力,而只滚动支持它的小部件(如文本小部件)?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-29 03:51:11

问题是self.canvas.bind_all创建了一个全局绑定。首先将<MouseWheel>绑定到第一个画布。然后,覆盖该绑定并将其绑定到第二个绑定。然后,覆盖该绑定并将其绑定到第三个绑定。

您可以在每次更改页面时更改全局绑定,或者使用bind而不是bind_all直接将绑定添加到每个画布。您的第三个选择是使您的绑定足够智能,可以滚动任何可见的画布。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50557438

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档