赞
踩
本文章效果图:
要让Frame滚动,最好的办法就是使用Canvas+Frame,下面给出一个封装好的ScrollFrame类:
- class ScrollFrame(tk.Frame):
- def __init__(self,master,width = 100,height = 100,**kw):
- self.frame = tk.Frame(master,**kw)
- self.width = width
- self.height = height
- self.is_use_mwsl = False
- if self.is_use_mwsl:
- self.mwsl = self.get_wheel_scroll_lines()
-
- self.canvas = tk.Canvas(self.frame) # 创建画布
- self.canvas.grid()
-
- self.scrolly=tk.Scrollbar(self.frame,orient="vertical",command=self.canvas.yview) #创建滚动条
- self.scrolly.grid(row = 0,column = 1,sticky = "ns")
- self.canvas.configure(yscrollcommand=self.scrolly.set)
-
- super().__init__(self.canvas) # 在画布上创建frame
- self.canvas.create_window((0,0),window=self,anchor='nw') # 要用create_window才能跟随画布滚动
- self.bind("<Configure>",self.updCanvas)
- self.canvas.grid(row = 0,column = 0,sticky = "nwse")
- self.rowconfigure(0,weight = 1)
- self.columnconfigure(0,weight = 1)
- self.canvas.bind("<MouseWheel>",self.wheelBind)
-
- def syncColor(self,event = None):
- self.canvas.config(bg = self.cget("bg"))
- def get_wheel_scroll_lines(self):
- SPI_GETWHEELSCROLLLINES = 0x0068
- user32 = ctypes.windll.user32
- buf = wintypes.INT()
- result = user32.SystemParametersInfoW(SPI_GETWHEELSCROLLLINES, 0, ctypes.byref(buf), 0)
- if result:
- return buf.value
- else:
- raise Exception("Failed to get wheel scroll lines")
-
- def wheelBind(self,event):
- if not self.is_use_mwsl:
- self.canvas.yview_scroll(-event.delta // 120, "units")
- else:
- self.canvas.yview_scroll(-event.delta // 120 * self.mwsl, "units")
-
- def updCanvas(self,event):
- self.canvas.config(bg = self.cget("bg"))
- self.canvas.configure(scrollregion=self.canvas.bbox("all"),width = self.width,height = self.height)
- self.update()
-
- def add(self,mod,**kw):
- mod.grid(**kw)
-
- def grid(self,**kw):
- tk.Grid.grid_configure(self.frame,**kw)
使用示例:
- scf = ScrollFrame(win,width = 600,height = 500,bd = 1,relief = "sunken")
- scf.grid(sticky = "nesw")
- for i in [tk.Button(scf,text = i) for i in range(100)]:
- scf.add(i,sticky = "we")
- scf.add(i,sticky = "we")
- scf.add(i,sticky = "we")
展示:
(标题栏颜色是因为gif渲染的时候导致的,本来是白的,如果要自定义标题栏请看上次的文章Python tkinter自定义标题栏-示例-CSDN博客)
通过继承这个ScrollFrame,还可以实现以下操作:
- class Chart(ScrollFrame):
- def __init__(self,master,title = [],value = [],bg = "white",fg = "black",font = ("",10),linesNum = True,**kw):
- super().__init__(master,**kw)
- self.title = title
- self.value = value
- self.linesNum = linesNum
- self.bg = bg
- self.fg = fg
- self.font = font
- self.config(bg = self.bg)
-
- self.buttonStyle = ttk.Style()
- self.labelStyle = ttk.Style()
- self.buttonStyle.configure("My.TButton",bg = bg,fg = fg)
- self.labelStyle.configure("My.TLabel",bg = bg,fg = fg)
- if self.title:
- self.draw()
- def draw(self):
- normallinecolumn = 0
- if self.linesNum:
- for i in range(len(self.value)):
- self.add(tk.Label(self,text = i + 1,bg = self.bg,fg = self.fg,font = (*self.font,"bold")),row = i * 2 + 3,column = 0)
- normallinecolumn = 1
-
- for i in range(len(self.title)):
- self.add(tk.Label(self,text = self.title[i],bg = self.bg,fg = self.fg,font = (*self.font,"bold")),row = 0,column = i * 2 + normallinecolumn * 3)
- self.add(ttk.Separator(self,orient = tk.VERTICAL),row = 0,column = i * 2 + 1 + normallinecolumn * 3,sticky = "ns",rowspan = len(self.value) * 2 + normallinecolumn * 3)
- self.add(ttk.Separator(self,orient = tk.HORIZONTAL),row = 1,column = 0,columnspan = len(self.title) * 2 + normallinecolumn * 3,sticky = "we")
- self.add(ttk.Separator(self,orient = tk.HORIZONTAL),row = 2,column = 0,columnspan = len(self.title) * 2 + normallinecolumn * 3,sticky = "we")
- if self.linesNum:
- self.add(ttk.Separator(self,orient = tk.VERTICAL),row = 0,column = 1,rowspan = len(self.value) * 2 + normallinecolumn * 3,sticky = "ns")
- self.add(ttk.Separator(self,orient = tk.VERTICAL),row = 0,column = 2,rowspan = len(self.value) * 2 + normallinecolumn * 3,sticky = "ns")
- for i in range(len(self.value)):
- for o in range(len(self.value[i])):
- self.add(tk.Label(self,text = self.value[i][o],bg = self.bg,fg = self.fg,font = self.font),row = i * 2 + 3,column = o * 2 + normallinecolumn * 3)
- self.add(ttk.Separator(self,orient = tk.HORIZONTAL),row = i * 2 + 4,column = 0,columnspan = len(self.title) * 2 + normallinecolumn * 3,sticky = "we")
- cht = Chart(win,bg = "white",fg = "blue",title = random.sample(list(range(0,100)),k = 10),value = [random.sample(list(range(0,100)),k = 10) for _ in range(0,100)],
- width = 500,height = 300)
- cht.grid(row = 1,column = 0,sticky = "nsew")
运行效果:
现在还有个问题就是表格框滚动鼠标滚轮的时候到最上面可能会滚动不上去,要往下一下再重新向上滚动才可以恢复。还有就是数据太多导致的窗口卡顿
备注:本文需要导入的库:
import tkinter as tk from tkinter import ttk import random import ctypes from ctypes import wintypes
制作不易,感谢阅读!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。