天天看点

tkinter 带滚动条的窗口实现界面切换

近期在开发一个小应用程序的过程中,需要在窗口中加入滚动条,还要实现点击按钮进行界面的切换,查找了一些资料,自己实现了带滚动条窗口的切换。

基本思路为:

1.在主窗口中设置一个画布控件,带滚动条;

2.在画布中加载第一个frame,并将滚动条滚动绑定到这个frame;

3.点击第一个frame上的按钮,在画布中加载第二个frame,并将滚动条滚动绑定到该frame上;

4.第二个frame上有返回第一个frame的按钮,以及退出整个整个应用程序的按钮。

完整代码如下:

# _*_ coding:utf-8 _*_
"""
@ 功能 : 带滚动条的窗口切换界面
@ author : sxy
@ create date : 2022/12/8
"""

from tkinter import *
# ----------------------------------------------------------------------            
#程序主界面
class MainFrame():
    def __init__(self,master=None):
        self.root=master      
        self.root.title('XX数据分析软件')
        
        self.WIDTH=1000
        self.HEIGHT=760
        # Place GUI on the center of screen
        self.ws = self.root.winfo_screenwidth()
        self.hs = self.root.winfo_screenheight()
        x = int((self.ws / 2) - (self.WIDTH / 2))
        y = int((self.hs / 2) - (self.HEIGHT / 2))
        self.root.geometry('{0:d}x{1:d}+{2:d}+{3:d}'.format(self.WIDTH, self.HEIGHT, x, y))
        #self.root.resizable(False,False)
        
        #创建画布,加滚动条
        self.mCanvas=Canvas(self.root)
        self.mCanvas.pack(side="left",fill="both", expand=True)
        myscrollbar=Scrollbar(self.mCanvas,orient="vertical",command=self.mCanvas.yview)      #创建滚动条
        myscrollbar.pack(side="right", fill="y")        
        self.mCanvas.configure(yscrollcommand=myscrollbar.set)
        
       #创建第一个页面并显示
        FirstPage=First(self.mCanvas)
        self.mCanvas.create_window((150,0),window=FirstPage,anchor='nw')    # 要用create_window才能跟随画布滚动
    
        FirstPage.bind("<Configure>",self.rollfunction)
        FirstPage.bind_all("<MouseWheel>", self._on_mousewheel)

    # 滚动函数
    def rollfunction(self,event):
        self.mCanvas.configure(scrollregion = self.mCanvas.bbox("all"))
        
    def _on_mousewheel(self,event):
        self.mCanvas.yview_scroll(int(-1 * (event.delta / 120)), "units")
        
#-------------------------------------------------------------------------
#第一个页面        
class First(Frame): # 继承Frame类
        
    def __init__(self,master=None):
        Frame.__init__(self,master)
        self.root=master
        
        self.lableFrameName=Label(self,text='XX数据分析软件—信息录入',
                                  font=('微软雅黑', 20))
        self.lableFrameName.grid(row=0,column=0,columnspan=4,pady=5,sticky='EW')

        self.labelProjectName=Label(self,text='项目名称:',font=('微软雅黑', 11))
        self.labelProjectName.grid(row=1,column=0)
        self.EntryProjectName=Entry(self,width=40)
        self.EntryProjectName.grid(row=1,column=1,sticky='EW')

        self.lableArea=Label(self,text='面积(㎡):',font=('微软雅黑', 11))
        self.EntryArea=Entry(self,width=10)
        self.lableArea.grid(row=1,column=2)
        self.EntryArea.grid(row=1,column=3,sticky='W')
             
        buttonConfirm=Button(self,text='确定',font=('微软雅黑', 11),width=15,
                             command=self.ok)     
        buttonConfirm.grid(row=2,column=2,sticky='W',padx=5,pady=10)
       
        buttonLoad=Button(self,text='清空',font=('微软雅黑', 11),width=15,
                                 command=self.clear)
        buttonLoad.grid(row=2,column=1,sticky='W',padx=5,pady=10)
        
        lableBlank=Label(self,text='             ',font=('微软雅黑', 30))
        lableBlank.grid(row=3,column=0,columnspan=4,sticky='EW')
        
    #----------------------------------------------------------------------------------------
    #跳转到模块选择页面
    def ok(self):        
        self.destroy()
        SecondPage=Second(self.root)      
        self.root.create_window((150,0),window=SecondPage,anchor='nw')    # 要用create_window才能跟随画布滚动
        self.root.yview('moveto',0.0)
        self.root.pack(side="left",fill="both", expand=True)
                 
    def clear(self):        
        self.EntryProjectName.delete(0,'end')
        self.EntryArea.delete(0,'end')  
            
#-------------------------------------------------------------------------        
#模块选择页面        
class Second(Frame):
    def __init__(self,master=None):
        Frame.__init__(self,master)
        self.root=master
        
        self.bind("<Configure>",self.rollfunction)
        self.bind_all("<MouseWheel>", self._on_mousewheel)
          
        lableFrameName=Label(self,text='XX数据分析软件—第二个界面',
                                  font=('微软雅黑', 20),width=40)
        lableFrameName.grid(row=0,columnspan=4,pady=5,sticky='EW')
        
        buttonBack=Button(self,text='返回上一页',font=('微软雅黑', 11),width=12,
                             command=self.back)     
        buttonBack.grid(row=1,column=0,padx=5,pady=10)

        buttonOk=Button(self,text='确定',font=('微软雅黑', 11),width=12,
                                 command=self.ok)
        buttonOk.grid(row=1,column=1,padx=5,pady=10)

        #----------------------------------------------------------------------------        
        
    def back(self):        
        self.destroy()
        FirstPage=First(self.root)
        self.root.create_window((150,0),window=FirstPage,anchor='nw')    # 要用create_window才能跟随画布滚动
        self.root.yview('moveto',0.0)
        
    def ok(self):
        self.master.master.destroy()
    
    # 滚动函数
    def rollfunction(self,event):
        self.root.configure(scrollregion = self.root.bbox("all"))
        
    def _on_mousewheel(self,event):
        self.root.yview_scroll(int(-1 * (event.delta / 120)), "units")
#------------------------------------------------------------------    
if __name__ == "__main__":
    
    root = Tk()
    app = MainFrame(root)
    root.mainloop()