From c860771118751915fd875d346f3351b733b89a9a Mon Sep 17 00:00:00 2001 From: cxykevin Date: Tue, 23 Apr 2024 22:31:34 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90scrollbar=E7=9A=84=E6=8B=96?= =?UTF-8?q?=E5=8A=A8=E8=A1=8C=E4=B8=BA=EF=BC=88=E6=9A=82=E6=9C=AA=E7=BB=91?= =?UTF-8?q?=E5=AE=9A=E6=BB=9A=E8=BD=AE=E4=BA=8B=E4=BB=B6=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- debug.py | 6 +-- magictk/frame.py | 29 ++++++++++++- magictk/scrollbar.py | 101 +++++++++++++++++++++++++++---------------- 3 files changed, 93 insertions(+), 43 deletions(-) diff --git a/debug.py b/debug.py index 991df8f..828e39f 100644 --- a/debug.py +++ b/debug.py @@ -85,8 +85,8 @@ if __name__ == "__main__": magictk.Entry(frame7, w=200).pack(side='left') frame7.pack() - frame8 = magictk.Container(win, h=10, container_h=30*6*5) - for i in range(5): + frame8 = magictk.Container(win, h=100, container_h=30*6*2) + for i in range(2): magictk.Button(frame8, text="Default", func=lambda s: print("Btn 1")).pack() magictk.ButtonFill(frame8, text="Primary", @@ -99,6 +99,6 @@ if __name__ == "__main__": func=lambda s: print("Btn 5")).pack() magictk.ButtonFill(frame8, color_type="danger", text="Danger", func=lambda s: print("Btn 6")).pack() - frame8.pack() + frame8.pack(expand="y") win.mainloop() diff --git a/magictk/frame.py b/magictk/frame.py index 39f3c86..e783daf 100644 --- a/magictk/frame.py +++ b/magictk/frame.py @@ -21,17 +21,42 @@ class Container(Frame): def scroll_callback(self, obj, pos): super().place(x=0, y=-pos, w=self.w-7, h=self.container_h) + def update_frame(self, *args, **kwargs): + self.w = self.root_frame.winfo_width() + self.h = self.root_frame.winfo_height() + # if (self.h >= self.container_h-2): + # # self.scroll.scroll_y = 0 + # # self.scroll.update_pos() + # # self.scroll.place_forget() + # pass + # else: + super().place(x=0, y=-self.scroll.get(), w=self.w-7, h=self.container_h) + self.scroll._r_allh = self.container_h + self.scroll._r_maxh = self.h + self.scroll.place(x=self.w-7, y=0, w=8, relheight=1) + self.scroll.h = self.h + scrolltmp = self.scroll.scroll_y*self.scroll.y_size + self.scroll.cal_bar() + self.scroll.update_pos() + if (self.scroll.y_size==0): + self.scroll.scroll_y=0 + else: + self.scroll.scroll_y = min(self.scroll.h-self.scroll.bar_len, + max(0, scrolltmp/self.scroll.y_size)) + def __init__(self, master, color=None, w=300, h=200, container_h=500, *args, **kwargs): self.root = master.root self.w = w self.h = h self.container_h = container_h - self.root_frame = Frame(master, width=w, height=h) + self.root_frame = Frame(master, width=w, height=self.container_h) super().__init__(self.root_frame, *args, **kwargs) super().place(x=0, y=0, w=self.w-7, h=container_h) self.scroll = ScrollBar(self.root_frame, - h=self.h, allh=self.container_h-self.h, maxh=self.h, callback=self.scroll_callback) + h=self.h, allh=self.container_h, maxh=self.h, callback=self.scroll_callback) self.scroll.place(x=self.w-7, y=0, w=8, relheight=1) + self.root_frame.bind("", self.update_frame) + # self.configure def pack(self, *args, **kwargs): self.root_frame.pack(*args, **kwargs) diff --git a/magictk/scrollbar.py b/magictk/scrollbar.py index 2923d46..3392b44 100644 --- a/magictk/scrollbar.py +++ b/magictk/scrollbar.py @@ -15,10 +15,15 @@ class ScrollBar: scroll_y = 0 y_size = 1.0 bar_len = 100 + _dis_event = False def cal_bar(self): - self.bar_len = max(self.h*self._r_maxh//self._r_allh, 20) - self.y_size = self._r_allh/(self.h-self.bar_len) + self.bar_len = self._r_maxh*self.h//self._r_allh + if (self.h-self.bar_len == 0): + self.y_size = 0 + else: + self.bar_len = max(20, self.bar_len) + self.y_size = (self._r_allh-self._r_maxh)/(self.h-self.bar_len) def __draw_corner(self, r_x, r_y, x, y, colors="#000000", rid="", bgcolor=None, **kwargs): if bgcolor is None: @@ -33,12 +38,16 @@ class ScrollBar: for j in i: if (r_x == 0): px = x+x_n+1 + zpx = x_n+1 else: px = x+6-x_n + zpx = 6-x_n if (r_y == 0): py = y+y_n+1 + zpy = y_n+1 else: py = y+3-y_n-1 + zpy = 3-y_n-1 if (j < 0): lcolor = -j else: @@ -52,7 +61,7 @@ class ScrollBar: px, py, px, py, width=0, fill=g_color) self.__fill_obj[rid].append(obj) - self.__fill_obj[rid+"_pos"].append([px, py]) + self.__fill_obj[rid+"_pos"].append([zpx, zpy]) self.__fill_obj[rid+"_pos2"].append([y_n, x_n]) x_n += 1 @@ -86,12 +95,21 @@ class ScrollBar: def pack(self, *args, **kwargs): self.canvas.pack(*args, **kwargs) + def pack_forget(self, *args, **kwargs): + self.canvas.pack_forget(*args, **kwargs) + def grid(self, *args, **kwargs): self.canvas.grid(*args, **kwargs) + def grid_forget(self, *args, **kwargs): + self.canvas.grid_forget(*args, **kwargs) + def place(self, *args, **kwargs): self.canvas.place(*args, **kwargs) + def place_forget(self, *args, **kwargs): + self.canvas.place_forget(*args, **kwargs) + def update_pos(self): for i in range(len(self.__fill_obj["upside"])): self.canvas.coords( @@ -100,46 +118,53 @@ class ScrollBar: self.__fill_obj["fgbar"][0], 1, 4+self.scroll_y, self.w-1, self.scroll_y+self.bar_len-4+1) for i in range(len(self.__fill_obj["bottomside"])): self.canvas.coords( - self.__fill_obj["bottomside"][i], int(self.__fill_obj["bottomside_pos"][i][0]), self.__fill_obj["bottomside_pos"][i][1]+self.scroll_y, int(self.__fill_obj["bottomside_pos"][i][0]), self.__fill_obj["bottomside_pos"][i][1]+self.scroll_y) + self.__fill_obj["bottomside"][i], int(self.__fill_obj["bottomside_pos"][i][0]), self.__fill_obj["bottomside_pos"][i][1]+self.scroll_y+self.bar_len-5, int(self.__fill_obj["bottomside_pos"][i][0]), self.__fill_obj["bottomside_pos"][i][1]+self.scroll_y+self.bar_len-5) def bind_event(self): - def mouse_press(event: tkinter.Event): - if (event.y >= self.scroll_y and event.y <= self.scroll_y+self.bar_len): - pass - else: - self.scroll_y = min(self.h-self.bar_len, - max(0, event.y-self.bar_len//2)) - self.move_start = event.y-self.scroll_y - for i in range(len(self.__fill_obj["upside"])): - self.canvas.itemconfig( - self.__fill_obj["upside"][i], fill=color_tmpl.mix_color( - self.color["background"], self.color["border_base"], int((1-self.border_info[self.__fill_obj["upside_pos2"][i][0]][self.__fill_obj["upside_pos2"][i][1]]/255)*1000)/1000)) - self.canvas.itemconfig( - self.__fill_obj["fgbar"][0], fill=self.color["border_base"]) - for i in range(len(self.__fill_obj["bottomside"])): - self.canvas.itemconfig( - self.__fill_obj["bottomside"][i], fill=color_tmpl.mix_color( - self.color["background"], self.color["border_base"], int((1-self.border_info[self.__fill_obj["bottomside_pos2"][i][0]][self.__fill_obj["bottomside_pos2"][i][1]]/255)*1000)/1000)) - self.update_pos() - def mouse_move(event: tkinter.Event): - delta_y = event.y-self.scroll_y - self.scroll_y = min(self.h-self.bar_len, - max(0, self.scroll_y+delta_y-self.move_start)) - self.callback(self, self.get()) - self.update_pos() + if (not self._dis_event): + delta_y = event.y-self.scroll_y + self.scroll_y = min(self.h-self.bar_len, + max(0, self.scroll_y+delta_y-self.move_start)) + self.callback(self, self.get()) + self.update_pos() + + def mouse_press(event: tkinter.Event): + if (not self._dis_event): + flag = False + if (event.y >= self.scroll_y and event.y <= self.scroll_y+self.bar_len): + pass + else: + self.scroll_y = min(self.h-self.bar_len, + max(0, event.y-self.bar_len//2)) + flag = True + self.move_start = event.y-self.scroll_y + for i in range(len(self.__fill_obj["upside"])): + self.canvas.itemconfig( + self.__fill_obj["upside"][i], fill=color_tmpl.mix_color( + self.color["background"], self.color["border_base"], int((1-self.border_info[self.__fill_obj["upside_pos2"][i][0]][self.__fill_obj["upside_pos2"][i][1]]/255)*1000)/1000)) + self.canvas.itemconfig( + self.__fill_obj["fgbar"][0], fill=self.color["border_base"]) + for i in range(len(self.__fill_obj["bottomside"])): + self.canvas.itemconfig( + self.__fill_obj["bottomside"][i], fill=color_tmpl.mix_color( + self.color["background"], self.color["border_base"], int((1-self.border_info[self.__fill_obj["bottomside_pos2"][i][0]][self.__fill_obj["bottomside_pos2"][i][1]]/255)*1000)/1000)) + if (flag): + self.update_pos() + mouse_move(event) def mouse_release(event: tkinter.Event): - for i in range(len(self.__fill_obj["upside"])): + if (not self._dis_event): + for i in range(len(self.__fill_obj["upside"])): + self.canvas.itemconfig( + self.__fill_obj["upside"][i], fill=color_tmpl.mix_color( + self.color["background"], self.color["border_light"], int((1-self.border_info[self.__fill_obj["upside_pos2"][i][0]][self.__fill_obj["upside_pos2"][i][1]]/255)*1000)/1000)) self.canvas.itemconfig( - self.__fill_obj["upside"][i], fill=color_tmpl.mix_color( - self.color["background"], self.color["border_light"], int((1-self.border_info[self.__fill_obj["upside_pos2"][i][0]][self.__fill_obj["upside_pos2"][i][1]]/255)*1000)/1000)) - self.canvas.itemconfig( - self.__fill_obj["fgbar"][0], fill=self.color["border_light"]) - for i in range(len(self.__fill_obj["bottomside"])): - self.canvas.itemconfig( - self.__fill_obj["bottomside"][i], fill=color_tmpl.mix_color( - self.color["background"], self.color["border_light"], int((1-self.border_info[self.__fill_obj["bottomside_pos2"][i][0]][self.__fill_obj["bottomside_pos2"][i][1]]/255)*1000)/1000)) + self.__fill_obj["fgbar"][0], fill=self.color["border_light"]) + for i in range(len(self.__fill_obj["bottomside"])): + self.canvas.itemconfig( + self.__fill_obj["bottomside"][i], fill=color_tmpl.mix_color( + self.color["background"], self.color["border_light"], int((1-self.border_info[self.__fill_obj["bottomside_pos2"][i][0]][self.__fill_obj["bottomside_pos2"][i][1]]/255)*1000)/1000)) self.canvas.bind("", mouse_move) self.canvas.bind("", mouse_press) @@ -155,6 +180,6 @@ class ScrollBar: def get(self): if (self.scroll_y+self.bar_len >= self.h): - return self._r_allh + return self._r_allh-self._r_maxh else: return int(min(self.scroll_y*self.y_size, self._r_allh))