提交 28c7a664 编写于 作者: 小康2022's avatar 小康2022 👍

version 2.3

上级 0a536ecb
......@@ -64,129 +64,6 @@ TEXT = ''
# 容器控件
class Canvas(tkinter.Canvas):
"""
画布类
用于承载虚拟的画布控件
"""
def __init__(
self,
master, # type: Tk
width: int,
height: int,
lock: bool = True,
expand: bool = True,
**kw
) -> None:
"""
### 参数说明
`master`: 父控件
`width`: 画布宽度
`height`: 画布高度
`lock`: 画布内控件的功能锁(False 时没有功能)
`expand`: 画布内控件是否能缩放
`**kw`: 与原 tkinter 模块内 Canvas 类的参数相同
"""
self.width = width
self.height = height
self.lock = lock
self.expand = expand
# 放缩比率
self.rate_x = 1
self.rate_y = 1
# 子控件列表(与事件绑定有关)
self.widget_list: list[_BaseWidget] = []
# 子item列表(与大小缩放有关)
self.item_dict = {} # type: dict[tkinter._CanvasItemId, tuple | list]
tkinter.Canvas.__init__(
self,
master,
width=width,
height=height,
highlightthickness=0,
**kw)
# 将实例添加到 Tk 的画布列表中
master.canvas_list.append(self)
def setlock(self, boolean: bool):
""" 设置画布锁 """
self.lock = boolean
self.master: Tk
if self.lock and self.expand:
self.master.zoom_update(self)
def create_text(self, *args, **kw):
# 重载:添加对 text 类型的 _CanvasItemId 的字体大小的控制
item = tkinter.Canvas.create_text(self, *args, **kw)
self.item_dict[item] = ('font', kw.get('font')[1])
return item
def create_image(self, *args, **kw):
# 重载:添加对 image 类型的 _CanvasItemId 的图像大小的控制
item = tkinter.Canvas.create_image(self, *args, **kw)
self.item_dict[item] = ['image', kw.get('image'), None]
return item
def create_rectangle(self, *args, **kw):
# 重载:添加对 rectangle 类型的 _CanvasItemId 的线条宽度的控制
item = tkinter.Canvas.create_rectangle(self, *args, **kw)
self.item_dict[item] = ('width', self.itemcget(item, 'width'))
return item
def create_line(self, *args, **kw):
# 重载:添加对 line 类型的 _CanvasItemId 的线条宽度的控制
item = tkinter.Canvas.create_line(self, *args, **kw)
self.item_dict[item] = ('width', self.itemcget(item, 'width'))
return item
def create_oval(self, *args, **kw):
# 重载:添加对 oval 类型的 _CanvasItemId 的线条宽度的控制
item = tkinter.Canvas.create_oval(self, *args, **kw)
self.item_dict[item] = ('width', self.itemcget(item, 'width'))
return item
def create_arc(self, *args, **kw): # NOTE: 可能有未知的 BUG
# 重载:添加对 arc 类型的 _CanvasItemId 的线条宽度的控制
item = tkinter.Canvas.create_arc(self, *args, **kw)
self.item_dict[item] = ('width', self.itemcget(item, 'width'))
return item
def create_polygon(self, *args, **kw): # NOTE: 可能有未知的 BUG
# 重载:添加对 polygon 类型的 _CanvasItemId 的线条宽度的控制
item = tkinter.Canvas.create_polygon(self, *args, **kw)
self.item_dict[item] = ('width', self.itemcget(item, 'width'))
return item
def create_bitmap(self, *args, **kw): # NOTE: 有待进一步研究
# 重载:目前仅有防报错作用
item = tkinter.Canvas.create_bitmap(self, *args, **kw)
self.item_dict[item] = (None, None)
return item
def create_window(self, *args, **kw): # NOTE: 有待进一步研究
# 重载:目前仅有防报错作用
item = tkinter.Canvas.create_window(self, *args, **kw)
self.item_dict[item] = (None, None)
return item
def itemconfigure(
self,
tagOrId, # type: str | tkinter._CanvasItemId
**kw
) -> dict[str, tuple[str, str, str, str, str]] | None:
# 重载:创建空image的_CanvasItemId时漏去对图像大小的控制
if type(kw.get('image')) == PhotoImage and not self.itemcget(tagOrId, 'image'):
self.item_dict[tagOrId] = ['image', kw.get('image'), None]
return tkinter.Canvas.itemconfigure(self, tagOrId, **kw)
class Tk(tkinter.Tk):
"""
Tk类
......@@ -287,7 +164,9 @@ class Tk(tkinter.Tk):
self._height = event.height
@staticmethod
def __zoom_relative(canvas: Canvas, rate_x: float, rate_y: float):
def __zoom_relative(canvas, # type: Canvas
rate_x: float,
rate_y: float):
""" 相对缩放 """
# 更新子画布控件的子虚拟画布控件位置数据
for widget in canvas.widget_list:
......@@ -303,7 +182,8 @@ class Tk(tkinter.Tk):
canvas.coords(item, coords)
@staticmethod
def __zoom_absolute(canvas: Canvas):
def __zoom_absolute(canvas # type: Canvas
):
""" 绝对缩放 """
for item, key in canvas.item_dict.items():
if key[0] == 'font': # NOTE: 字体缩小时有 BUG
......@@ -324,7 +204,9 @@ class Tk(tkinter.Tk):
canvas.itemconfigure(item, image=key[2])
@staticmethod
def __touch(event: tkinter.Event, canvas: Canvas) -> None:
def __touch(event: tkinter.Event,
canvas # type: Canvas
) -> None:
""" 绑定鼠标触碰控件事件 """
if canvas.lock:
for widget in canvas.widget_list:
......@@ -332,7 +214,9 @@ class Tk(tkinter.Tk):
widget.touch(event)
@staticmethod
def __press(event: tkinter.Event, canvas: Canvas) -> None:
def __press(event: tkinter.Event,
canvas # type: Canvas
) -> None:
""" 绑定鼠标左键按下事件 """
if canvas.lock:
for widget in canvas.widget_list:
......@@ -340,7 +224,9 @@ class Tk(tkinter.Tk):
widget.press(event)
@staticmethod
def __release(event: tkinter.Event, canvas: Canvas) -> None:
def __release(event: tkinter.Event,
canvas # type: Canvas
) -> None:
""" 绑定鼠标左键松开事件 """
if canvas.lock:
for widget in canvas.widget_list:
......@@ -349,7 +235,9 @@ class Tk(tkinter.Tk):
widget.touch(event)
@staticmethod
def __mousewheel(event: tkinter.Event, canvas: Canvas) -> None:
def __mousewheel(event: tkinter.Event,
canvas # type: Canvas
) -> None:
""" 绑定鼠标滚轮滚动事件 """
if canvas.lock:
for widget in canvas.widget_list:
......@@ -402,6 +290,129 @@ class Tk(tkinter.Tk):
zoom_update = __zoom_absolute
class Canvas(tkinter.Canvas):
"""
画布类
用于承载虚拟的画布控件
"""
def __init__(
self,
master: Tk,
width: int,
height: int,
lock: bool = True,
expand: bool = True,
**kw
) -> None:
"""
### 参数说明
`master`: 父控件
`width`: 画布宽度
`height`: 画布高度
`lock`: 画布内控件的功能锁(False 时没有功能)
`expand`: 画布内控件是否能缩放
`**kw`: 与原 tkinter 模块内 Canvas 类的参数相同
"""
self.width = width
self.height = height
self.lock = lock
self.expand = expand
# 放缩比率
self.rate_x = 1
self.rate_y = 1
# 子控件列表(与事件绑定有关)
self.widget_list: list[_BaseWidget] = []
# 子item列表(与大小缩放有关)
self.item_dict = {} # type: dict[tkinter._CanvasItemId, tuple | list]
tkinter.Canvas.__init__(
self,
master,
width=width,
height=height,
highlightthickness=0,
**kw)
# 将实例添加到 Tk 的画布列表中
master.canvas_list.append(self)
def setlock(self, boolean: bool):
""" 设置画布锁 """
self.lock = boolean
self.master: Tk
if self.lock and self.expand:
self.master.zoom_update(self)
def create_text(self, *args, **kw):
# 重载:添加对 text 类型的 _CanvasItemId 的字体大小的控制
item = tkinter.Canvas.create_text(self, *args, **kw)
self.item_dict[item] = ('font', kw.get('font')[1])
return item
def create_image(self, *args, **kw):
# 重载:添加对 image 类型的 _CanvasItemId 的图像大小的控制
item = tkinter.Canvas.create_image(self, *args, **kw)
self.item_dict[item] = ['image', kw.get('image'), None]
return item
def create_rectangle(self, *args, **kw):
# 重载:添加对 rectangle 类型的 _CanvasItemId 的线条宽度的控制
item = tkinter.Canvas.create_rectangle(self, *args, **kw)
self.item_dict[item] = ('width', self.itemcget(item, 'width'))
return item
def create_line(self, *args, **kw):
# 重载:添加对 line 类型的 _CanvasItemId 的线条宽度的控制
item = tkinter.Canvas.create_line(self, *args, **kw)
self.item_dict[item] = ('width', self.itemcget(item, 'width'))
return item
def create_oval(self, *args, **kw):
# 重载:添加对 oval 类型的 _CanvasItemId 的线条宽度的控制
item = tkinter.Canvas.create_oval(self, *args, **kw)
self.item_dict[item] = ('width', self.itemcget(item, 'width'))
return item
def create_arc(self, *args, **kw): # NOTE: 可能有未知的 BUG
# 重载:添加对 arc 类型的 _CanvasItemId 的线条宽度的控制
item = tkinter.Canvas.create_arc(self, *args, **kw)
self.item_dict[item] = ('width', self.itemcget(item, 'width'))
return item
def create_polygon(self, *args, **kw): # NOTE: 可能有未知的 BUG
# 重载:添加对 polygon 类型的 _CanvasItemId 的线条宽度的控制
item = tkinter.Canvas.create_polygon(self, *args, **kw)
self.item_dict[item] = ('width', self.itemcget(item, 'width'))
return item
def create_bitmap(self, *args, **kw): # NOTE: 有待进一步研究
# 重载:目前仅有防报错作用
item = tkinter.Canvas.create_bitmap(self, *args, **kw)
self.item_dict[item] = (None, None)
return item
def create_window(self, *args, **kw): # NOTE: 有待进一步研究
# 重载:目前仅有防报错作用
item = tkinter.Canvas.create_window(self, *args, **kw)
self.item_dict[item] = (None, None)
return item
def itemconfigure(
self,
tagOrId, # type: str | tkinter._CanvasItemId
**kw
) -> dict[str, tuple[str, str, str, str, str]] | None:
# 重载:创建空image的_CanvasItemId时漏去对图像大小的控制
if type(kw.get('image')) == PhotoImage and not self.itemcget(tagOrId, 'image'):
self.item_dict[tagOrId] = ['image', kw.get('image'), None]
return tkinter.Canvas.itemconfigure(self, tagOrId, **kw)
# 控件基类
......@@ -1186,7 +1197,7 @@ def gradient_color(
def _test():
""" 测试函数 """
def _tip():
def tip():
""" 弹出提示框 """
label = CanvasLabel(canvas,
700 * canvas.rate_x, 550 * canvas.rate_y,
......@@ -1195,10 +1206,16 @@ def _test():
font=('楷体', round(15 * canvas.rate_x)))
move_widget(canvas, label, 0, -120 * canvas.rate_y, 0.25, 'shake')
root = Tk('Test', '960x540', None, 0.9)
def shutdown():
""" 关闭窗口 """
import tkinter.messagebox
if tkinter.messagebox.askquestion('温馨提示', '是否退出程序?'):
root.quit()
root = Tk('Test', '960x540', alpha=0.9, shutdown=shutdown)
canvas = Canvas(root, 960, 540)
canvas.pack(expand=True, fill='both')
CanvasButton(canvas, 50, 100, 100, 25, '测试', command=_tip)
CanvasButton(canvas, 50, 100, 100, 25, '测试', command=tip)
CanvasEntry(canvas, 200, 100, 200, 25, ('输入框', '点击输入'))
CanvasText(canvas, 50, 200, 350, 200, limit=400)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册