当前位置:   article > 正文

python tkinter滚动Frame组件+表格框组件_tkinter 带滚动条的frame

tkinter 带滚动条的frame

本文章效果图:

要让Frame滚动,最好的办法就是使用Canvas+Frame,下面给出一个封装好的ScrollFrame类:
 

  1. class ScrollFrame(tk.Frame):
  2. def __init__(self,master,width = 100,height = 100,**kw):
  3. self.frame = tk.Frame(master,**kw)
  4. self.width = width
  5. self.height = height
  6. self.is_use_mwsl = False
  7. if self.is_use_mwsl:
  8. self.mwsl = self.get_wheel_scroll_lines()
  9. self.canvas = tk.Canvas(self.frame) # 创建画布
  10. self.canvas.grid()
  11. self.scrolly=tk.Scrollbar(self.frame,orient="vertical",command=self.canvas.yview) #创建滚动条
  12. self.scrolly.grid(row = 0,column = 1,sticky = "ns")
  13. self.canvas.configure(yscrollcommand=self.scrolly.set)
  14. super().__init__(self.canvas) # 在画布上创建frame
  15. self.canvas.create_window((0,0),window=self,anchor='nw') # 要用create_window才能跟随画布滚动
  16. self.bind("<Configure>",self.updCanvas)
  17. self.canvas.grid(row = 0,column = 0,sticky = "nwse")
  18. self.rowconfigure(0,weight = 1)
  19. self.columnconfigure(0,weight = 1)
  20. self.canvas.bind("<MouseWheel>",self.wheelBind)
  21. def syncColor(self,event = None):
  22. self.canvas.config(bg = self.cget("bg"))
  23. def get_wheel_scroll_lines(self):
  24. SPI_GETWHEELSCROLLLINES = 0x0068
  25. user32 = ctypes.windll.user32
  26. buf = wintypes.INT()
  27. result = user32.SystemParametersInfoW(SPI_GETWHEELSCROLLLINES, 0, ctypes.byref(buf), 0)
  28. if result:
  29. return buf.value
  30. else:
  31. raise Exception("Failed to get wheel scroll lines")
  32. def wheelBind(self,event):
  33. if not self.is_use_mwsl:
  34. self.canvas.yview_scroll(-event.delta // 120, "units")
  35. else:
  36. self.canvas.yview_scroll(-event.delta // 120 * self.mwsl, "units")
  37. def updCanvas(self,event):
  38. self.canvas.config(bg = self.cget("bg"))
  39. self.canvas.configure(scrollregion=self.canvas.bbox("all"),width = self.width,height = self.height)
  40. self.update()
  41. def add(self,mod,**kw):
  42. mod.grid(**kw)
  43. def grid(self,**kw):
  44. tk.Grid.grid_configure(self.frame,**kw)

使用示例:

  1. scf = ScrollFrame(win,width = 600,height = 500,bd = 1,relief = "sunken")
  2. scf.grid(sticky = "nesw")
  3. for i in [tk.Button(scf,text = i) for i in range(100)]:
  4. scf.add(i,sticky = "we")
  5. scf.add(i,sticky = "we")
  6. scf.add(i,sticky = "we")

展示:

(标题栏颜色是因为gif渲染的时候导致的,本来是白的,如果要自定义标题栏请看上次的文章Python tkinter自定义标题栏-示例-CSDN博客

通过继承这个ScrollFrame,还可以实现以下操作:

  1. class Chart(ScrollFrame):
  2. def __init__(self,master,title = [],value = [],bg = "white",fg = "black",font = ("",10),linesNum = True,**kw):
  3. super().__init__(master,**kw)
  4. self.title = title
  5. self.value = value
  6. self.linesNum = linesNum
  7. self.bg = bg
  8. self.fg = fg
  9. self.font = font
  10. self.config(bg = self.bg)
  11. self.buttonStyle = ttk.Style()
  12. self.labelStyle = ttk.Style()
  13. self.buttonStyle.configure("My.TButton",bg = bg,fg = fg)
  14. self.labelStyle.configure("My.TLabel",bg = bg,fg = fg)
  15. if self.title:
  16. self.draw()
  17. def draw(self):
  18. normallinecolumn = 0
  19. if self.linesNum:
  20. for i in range(len(self.value)):
  21. self.add(tk.Label(self,text = i + 1,bg = self.bg,fg = self.fg,font = (*self.font,"bold")),row = i * 2 + 3,column = 0)
  22. normallinecolumn = 1
  23. for i in range(len(self.title)):
  24. 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)
  25. 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)
  26. self.add(ttk.Separator(self,orient = tk.HORIZONTAL),row = 1,column = 0,columnspan = len(self.title) * 2 + normallinecolumn * 3,sticky = "we")
  27. self.add(ttk.Separator(self,orient = tk.HORIZONTAL),row = 2,column = 0,columnspan = len(self.title) * 2 + normallinecolumn * 3,sticky = "we")
  28. if self.linesNum:
  29. self.add(ttk.Separator(self,orient = tk.VERTICAL),row = 0,column = 1,rowspan = len(self.value) * 2 + normallinecolumn * 3,sticky = "ns")
  30. self.add(ttk.Separator(self,orient = tk.VERTICAL),row = 0,column = 2,rowspan = len(self.value) * 2 + normallinecolumn * 3,sticky = "ns")
  31. for i in range(len(self.value)):
  32. for o in range(len(self.value[i])):
  33. 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)
  34. self.add(ttk.Separator(self,orient = tk.HORIZONTAL),row = i * 2 + 4,column = 0,columnspan = len(self.title) * 2 + normallinecolumn * 3,sticky = "we")
  1. 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)],
  2. width = 500,height = 300)
  3. cht.grid(row = 1,column = 0,sticky = "nsew")

运行效果:

现在还有个问题就是表格框滚动鼠标滚轮的时候到最上面可能会滚动不上去,要往下一下再重新向上滚动才可以恢复。还有就是数据太多导致的窗口卡顿

备注:本文需要导入的库:

  1. import tkinter as tk
  2. from tkinter import ttk
  3. import random
  4. import ctypes
  5. from ctypes import wintypes

制作不易,感谢阅读!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/975498
推荐阅读
相关标签
  

闽ICP备14008679号