优化submenu(10000数据量不卡)
This commit is contained in:
parent
db3f0b2445
commit
ad0dbc33a7
|
@ -2,35 +2,15 @@ import json
|
||||||
import tkinter
|
import tkinter
|
||||||
import sys
|
import sys
|
||||||
from tkinter import ttk
|
from tkinter import ttk
|
||||||
from tkinter import font as tkfont
|
|
||||||
try:
|
|
||||||
import color_tmpl
|
|
||||||
except ImportError:
|
|
||||||
from magictk import color_tmpl
|
from magictk import color_tmpl
|
||||||
try:
|
|
||||||
import photoload
|
|
||||||
except ImportError:
|
|
||||||
from magictk import photoload
|
from magictk import photoload
|
||||||
|
from magictk import fontconfig
|
||||||
|
|
||||||
transcolor = "#41342F"
|
transcolor = "#41342F"
|
||||||
usetrans = sys.platform.startswith('win')
|
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:
|
class MenuObjs:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.menu_lst = []
|
self.menu_lst = []
|
||||||
|
@ -60,6 +40,7 @@ class Menu:
|
||||||
__y_move = 0
|
__y_move = 0
|
||||||
___last_move = 1
|
___last_move = 1
|
||||||
___last_highlight = 0
|
___last_highlight = 0
|
||||||
|
__load_y_size = 10
|
||||||
ht = 12
|
ht = 12
|
||||||
lt = 22
|
lt = 22
|
||||||
ft = 34
|
ft = 34
|
||||||
|
@ -102,7 +83,8 @@ class Menu:
|
||||||
n += 1
|
n += 1
|
||||||
self.___last_move = self.__y_move
|
self.___last_move = self.__y_move
|
||||||
n = 0
|
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):
|
if (len(i) != 0):
|
||||||
self.canvas.itemconfigure(
|
self.canvas.itemconfigure(
|
||||||
self.__itemsf[n], justify=tkinter.LEFT, **i)
|
self.__itemsf[n], justify=tkinter.LEFT, **i)
|
||||||
|
@ -119,29 +101,35 @@ class Menu:
|
||||||
y = event.y
|
y = event.y
|
||||||
self.__last_highlight = max(
|
self.__last_highlight = max(
|
||||||
-1, min(len(self.__items), int((y-self.ht-self.__y_move)//self.ft)))
|
-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)):
|
for i in self.__items:
|
||||||
if (self.___last_highlight != -2):
|
|
||||||
self.canvas.itemconfig(
|
self.canvas.itemconfig(
|
||||||
self.__items[self.___last_highlight], fill=self.color["background"])
|
i, fill=self.color["background"])
|
||||||
self.___last_highlight = -2
|
|
||||||
elif (self.___last_highlight != self.__last_highlight):
|
|
||||||
self.canvas.itemconfig(
|
self.canvas.itemconfig(
|
||||||
self.__items[self.__last_highlight], fill=self.color["placeholder_light"])
|
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):
|
def close(self, *args):
|
||||||
self.__close_mode = 1
|
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):
|
if (self.__closecallback is not None):
|
||||||
self.__closecallback(self)
|
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):
|
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.__closecallback = closecallback
|
||||||
self.font = (use_font, fontsize)
|
self.font = (use_font, fontsize)
|
||||||
self.__items = []
|
self.__items = []
|
||||||
self.__itemsf = []
|
self.__itemsf = []
|
||||||
|
self.__itemsid = []
|
||||||
|
self.__real_y_move = 0
|
||||||
self.menuobj = menuobj
|
self.menuobj = menuobj
|
||||||
self.w = w
|
self.w = w
|
||||||
self.h = h
|
self.h = h
|
||||||
|
@ -177,11 +165,13 @@ class Menu:
|
||||||
|
|
||||||
def __draw_menu(self):
|
def __draw_menu(self):
|
||||||
n = 0
|
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(
|
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))
|
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(
|
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"]))
|
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
|
n += 1
|
||||||
|
|
||||||
def __draw_corner(self, r_x, r_y, x, y, **kwargs):
|
def __draw_corner(self, r_x, r_y, x, y, **kwargs):
|
||||||
|
@ -234,6 +224,8 @@ class Menu:
|
||||||
|
|
||||||
def __bind_scroll(self):
|
def __bind_scroll(self):
|
||||||
def scrollwheel(event: tkinter.Event, setdelta=None):
|
def scrollwheel(event: tkinter.Event, setdelta=None):
|
||||||
|
if (len(self.menuobj.menu_lst) <= 8):
|
||||||
|
return
|
||||||
if (setdelta is None):
|
if (setdelta is None):
|
||||||
delta = event.delta
|
delta = event.delta
|
||||||
else:
|
else:
|
||||||
|
@ -241,10 +233,33 @@ class Menu:
|
||||||
if sys.platform.startswith('win'):
|
if sys.platform.startswith('win'):
|
||||||
delta //= 120
|
delta //= 120
|
||||||
if delta > 0:
|
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:
|
else:
|
||||||
self.__y_move = max(
|
if (self.__real_y_move != -(len(self.menuobj.menu_lst)*self.ft-self.h+8)):
|
||||||
-max(0, len(self.__items)*self.ft+self.ht-self.h), self.__y_move+delta)
|
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'):
|
if sys.platform.startswith('win'):
|
||||||
self.toplevel.bind_all("<MouseWheel>", scrollwheel)
|
self.toplevel.bind_all("<MouseWheel>", scrollwheel)
|
||||||
|
@ -258,8 +273,8 @@ class Menu:
|
||||||
|
|
||||||
def __click(self, event):
|
def __click(self, event):
|
||||||
click_item = max(
|
click_item = max(
|
||||||
-1, min(len(self.__items), int((event.y-self.ht-self.__y_move)//self.ft)))
|
-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.__items)):
|
if (click_item == -1 or self.__last_highlight >= len(self.menuobj.menu_func)):
|
||||||
return
|
return
|
||||||
self.close()
|
self.close()
|
||||||
self.menuobj.menu_func[click_item](self, click_item)
|
self.menuobj.menu_func[click_item](self, click_item)
|
||||||
|
|
Loading…
Reference in New Issue