优化submenu(10000数据量不卡)

This commit is contained in:
cxykevin 2024-04-14 14:46:09 +08:00
parent db3f0b2445
commit ad0dbc33a7
1 changed files with 57 additions and 42 deletions

View File

@ -2,35 +2,15 @@ import json
import tkinter
import sys
from tkinter import ttk
from tkinter import font as tkfont
try:
import color_tmpl
except ImportError:
from magictk import color_tmpl
try:
import photoload
except ImportError:
from magictk import photoload
from magictk import color_tmpl
from magictk import photoload
from magictk import fontconfig
transcolor = "#41342F"
usetrans = sys.platform.startswith('win')
def set_font():
global use_font
font_family = ["Helvetica Neue", "Helvetica", "PingFang SC", "Hiragino Sans GB",
"Microsoft YaHei",
"微软雅黑",
"Arial", "sans-serif"]
t_family = tkfont.families(root=None, displayof=None)
for i in font_family:
if i in t_family:
use_font = i
break
else:
print("Unknown font")
class MenuObjs:
def __init__(self):
self.menu_lst = []
@ -60,6 +40,7 @@ class Menu:
__y_move = 0
___last_move = 1
___last_highlight = 0
__load_y_size = 10
ht = 12
lt = 22
ft = 34
@ -102,7 +83,8 @@ class Menu:
n += 1
self.___last_move = self.__y_move
n = 0
for i in self.menuobj.menu_effect:
for i_tmp in range((-self.__real_y_move+self.__y_move)//self.ft, min((-self.__real_y_move+self.__y_move)//self.ft+len(self.__items), len(self.menuobj.menu_effect))):
i = self.menuobj.menu_effect[i_tmp]
if (len(i) != 0):
self.canvas.itemconfigure(
self.__itemsf[n], justify=tkinter.LEFT, **i)
@ -119,29 +101,35 @@ class Menu:
y = event.y
self.__last_highlight = max(
-1, min(len(self.__items), int((y-self.ht-self.__y_move)//self.ft)))
if (self.__last_highlight == -1 or self.__last_highlight >= len(self.__items)):
if (self.___last_highlight != -2):
for i in self.__items:
self.canvas.itemconfig(
self.__items[self.___last_highlight], fill=self.color["background"])
self.___last_highlight = -2
elif (self.___last_highlight != self.__last_highlight):
i, fill=self.color["background"])
self.canvas.itemconfig(
self.__items[self.__last_highlight], fill=self.color["placeholder_light"])
self.canvas.itemconfig(
self.__items[self.___last_highlight], fill=self.color["background"])
self.___last_highlight = self.__last_highlight
def close(self, *args):
self.__close_mode = 1
if sys.platform.startswith('win'):
self.toplevel.unbind_all("<MouseWheel>")
elif sys.platform.startswith('darwin'):
self.toplevel.unbind_all("<MouseWheel>")
else:
self.toplevel.unbind_all(
"<Button-4>")
self.toplevel.unbind_all(
"<Button-5>")
if (self.__closecallback is not None):
self.__closecallback(self)
def __init__(self, root, menuobj: MenuObjs, w=200, h=300, x=100, y=300, color_list: None | dict = None, closeonleave=True, fontsize=10, closecallback=None):
set_font()
global use_font
use_font = fontconfig.getfont()
self.__closecallback = closecallback
self.font = (use_font, fontsize)
self.__items = []
self.__itemsf = []
self.__itemsid = []
self.__real_y_move = 0
self.menuobj = menuobj
self.w = w
self.h = h
@ -177,11 +165,13 @@ class Menu:
def __draw_menu(self):
n = 0
for i in self.menuobj.menu_lst:
for i_tmp in range(0, min(self.__load_y_size, len(self.menuobj.menu_lst))):
i = self.menuobj.menu_lst[i_tmp]
self.__items.append(self.canvas.create_rectangle(
2, n*self.ft+self.ht, self.w, (n+1)*self.ft+self.ht, fill=self.color["background"], width=0))
self.__itemsf.append(self.canvas.create_text(
10, n*self.ft+self.ht, text=i, font=self.font, justify=tkinter.LEFT, fill=self.color["regular_text"]))
self.__itemsid.append(n)
n += 1
def __draw_corner(self, r_x, r_y, x, y, **kwargs):
@ -234,6 +224,8 @@ class Menu:
def __bind_scroll(self):
def scrollwheel(event: tkinter.Event, setdelta=None):
if (len(self.menuobj.menu_lst) <= 8):
return
if (setdelta is None):
delta = event.delta
else:
@ -241,10 +233,33 @@ class Menu:
if sys.platform.startswith('win'):
delta //= 120
if delta > 0:
self.__y_move = min(0, self.__y_move+delta)
if (self.__real_y_move != 0):
self.__y_move += delta
self.__real_y_move = min(0, self.__real_y_move+delta)
else:
self.__y_move = max(
-max(0, len(self.__items)*self.ft+self.ht-self.h), self.__y_move+delta)
if (self.__real_y_move != -(len(self.menuobj.menu_lst)*self.ft-self.h+8)):
self.__y_move += delta
self.__real_y_move = max(self.__real_y_move+delta,
-(len(self.menuobj.menu_lst)*self.ft-self.h+8))
if (self.__y_move > 0):
self.__y_move -= self.ft
self.__items.insert(0, self.__items.pop())
self.__itemsf.insert(0, self.__itemsf.pop())
self.__itemsid.insert(0, self.__itemsid.pop()-10)
self.__mouse_move(event)
if (self.__itemsid[0] >= 0):
self.canvas.itemconfigure(
self.__itemsf[0], text=self.menuobj.menu_lst[self.__itemsid[0]])
elif (self.__y_move < -self.ft+1):
self.__y_move += self.ft
self.__items.append(self.__items.pop(0))
self.__itemsf.append(self.__itemsf.pop(0))
self.__itemsid.append(self.__itemsid.pop(0)+10)
self.__mouse_move(event)
if (self.__itemsid[-1] < len(self.menuobj.menu_lst)):
self.canvas.itemconfigure(
self.__itemsf[-1], text=self.menuobj.menu_lst[self.__itemsid[-1]])
if sys.platform.startswith('win'):
self.toplevel.bind_all("<MouseWheel>", scrollwheel)
@ -258,8 +273,8 @@ class Menu:
def __click(self, event):
click_item = max(
-1, min(len(self.__items), int((event.y-self.ht-self.__y_move)//self.ft)))
if (click_item == -1 or self.__last_highlight >= len(self.__items)):
-1, min(len(self.menuobj.menu_func), int((event.y-self.ht-self.__real_y_move)//self.ft)))
if (click_item == -1 or self.__last_highlight >= len(self.menuobj.menu_func)):
return
self.close()
self.menuobj.menu_func[click_item](self, click_item)