Использование полосы прокрутки в нескольких вкладках Python Tkinter - PullRequest
0 голосов
/ 28 мая 2018

Я создал многостраничную программу (используя Python 2.7 и Tkinter на Mac) с кнопками навигации между страницами.Я хочу иметь возможность использовать полосу прокрутки на некоторых страницах, но когда я добавляю код полосы прокрутки для каждой страницы, прокручивается только последняя страница с добавленным кодом полосы прокрутки.Полоса прокрутки работает отлично (я понимаю, как это сделать), но кажется, что только одна страница может иметь рабочую полосу прокрутки одновременно.Зачем?Этот точный вопрос (почти) был задан несколько лет назад здесь ( Панель прокрутки Python Tkinter в нескольких вкладках ), но так и не получил ответа.Я также пытался поместить код полосы прокрутки в «главное окно» и код класса «создать новый файл», но случались забавные вещи.Вот основная версия того, что я пытаюсь сделать:

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()

Есть ли способ прокрутки каждой страницы или мне нужно отказаться от возможности прокручивать несколько виджетов на каждой странице?и просто прокручивать виджеты, которые его поддерживают (например, текстовый виджет)?

1 Ответ

0 голосов
/ 28 мая 2018

Проблема в том, что self.canvas.bind_all создает глобальную привязку.Сначала вы связываете <MouseWheel> с первым холстом.Затем вы переопределяете эту привязку и привязываете ее ко второй.Затем вы переопределяете эту привязку и привязываете ее к третьей.

Вам нужно либо изменять глобальную привязку каждый раз, когда вы меняете страницу, либо добавлять привязку к каждому холсту напрямую с помощью bind вместо * 1006.*.Третий вариант - сделать привязку достаточно умной для прокрутки любого видимого холста.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...