Skip to content

Commit 2aac864

Browse files
committed
写完了,上传
1 parent 183bf0c commit 2aac864

File tree

8 files changed

+250
-2
lines changed

8 files changed

+250
-2
lines changed

README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,11 @@
1-
# mctoast
2-
一个基于tkinter的显示minecraft风格toast库
1+
# 🍞mctoast
2+
一个基于tkinter的,用于显示minecraft风格的toast的库
3+
目前被[CamMoitor](https://github.com/SystemFileB/CamMonitor_Server)使用
4+
5+
## ⚙️使用方法
6+
见wiki
7+
8+
## ⚠️版权信息
9+
- 这个库与Mojang,Microsoft**没有任何关系**,且**不使用**client.jar,.minecraft/assets文件夹下的**任何文件**
10+
- Toast纹理来自[VanillaXBR](https://modrinth.com/resourcepack/vanillaxbr),基于[CC-BY-NC-4.0](https://creativecommons.org/licenses/by-nc/4.0/legalcode)许可证开源
11+
- 若遇到了相关的许可证问题,请第一时间[提交issue](https://github.com/SystemFileB/mctoast/issues)并加上 版权或许可证问题 标签

assets/mctoast/fonts/unifont.otf

5.08 MB
Binary file not shown.
512 Bytes
Loading

assets/mctoast/textures/recipe.png

507 Bytes
Loading

assets/mctoast/textures/system.png

747 Bytes
Loading

mctoast.code-workspace

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"folders": [
3+
{
4+
"path": "."
5+
}
6+
],
7+
"settings": {}
8+
}

mctoast.py

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
#!/usr/bin/python3
2+
import tkinter as tk
3+
import os
4+
import time
5+
from PIL import Image, ImageDraw, ImageFont, ImageTk
6+
import _thread as thread
7+
from threading import Thread,Event
8+
path=os.path.dirname(__file__)
9+
pathjoin=os.path.join
10+
toasts=[None,None,None,None,None]
11+
12+
# 定义常量
13+
ADVANCEMENT = pathjoin(path, "assets","mctoast","textures","advancement.png")
14+
RECIPE = pathjoin(path, "assets","mctoast","textures","recipe.png")
15+
SYSTEM = pathjoin(path, "assets","mctoast","textures","system.png")
16+
17+
def generate_image(toast, image_path, text1, color1, text2, color2):
18+
"""生成Toast图片"""
19+
# 打开背景图片并缩放
20+
background_image = Image.open(toast).resize((320, 64))
21+
22+
# 打开小图片并缩放
23+
if image_path:
24+
small_image = Image.open(image_path).resize((30, 30))
25+
background_image.paste(small_image, (17, 17))
26+
27+
# 创建一个绘图对象
28+
draw = ImageDraw.Draw(background_image)
29+
30+
# 加载字体
31+
font = ImageFont.truetype(pathjoin(path,"assets","mctoast","fonts","unifont.otf"), 15)
32+
33+
if toast==SYSTEM:
34+
if text1 and color1:
35+
draw.text((34, 13), text1, fill=color1, font=font)
36+
if text2 and color2:
37+
draw.text((34, 35), text2, fill=color2, font=font)
38+
else:
39+
# 在指定位置绘制文字
40+
if text1 and color1:
41+
draw.text((60, 13), text1, fill=color1, font=font)
42+
if text2 and color2:
43+
draw.text((60, 35), text2, fill=color2, font=font)
44+
45+
# 将 Pillow 图片转换为 PhotoImage
46+
return ImageTk.PhotoImage(background_image)
47+
48+
class ToastWindowUI:
49+
def __init__(self, master=None, data_pool=None):
50+
# build ui
51+
self.root = tk.Tk(master)
52+
self.root.configure(
53+
background="#EEEEEE",
54+
borderwidth=0,
55+
height=200,
56+
takefocus=False,
57+
width=200)
58+
self.root.geometry("320x320+{}+0".format(self.root.winfo_screenwidth()-320))
59+
self.root.withdraw()
60+
self.root.overrideredirect("true")
61+
self.root.title("MCToast")
62+
self.root.attributes("-topmost", "true")
63+
self.root.attributes("-transparentcolor", "#EEEEEE")
64+
self.set_no_focus()
65+
self.set_no_focus()
66+
self.root.resizable(False, False)
67+
self.canvas = tk.Canvas(self.root, width=320, height=320, bg="#EEEEEE", highlightthickness=0)
68+
self.canvas.place(x=0,y=0)
69+
70+
def set_no_focus(self):
71+
"""设置窗口为无焦点窗口并穿透鼠标点击"""
72+
import ctypes
73+
if os.name == 'nt': # Windows
74+
GWL_EXSTYLE = -20
75+
WS_EX_NOACTIVATE = 0x08000000
76+
WS_EX_TRANSPARENT = 0x00000020
77+
WS_EX_LAYERED = 0x00080000
78+
hwnd = ctypes.windll.user32.GetParent(self.root.winfo_id())
79+
style = ctypes.windll.user32.GetWindowLongW(hwnd, GWL_EXSTYLE)
80+
style = style | WS_EX_NOACTIVATE | WS_EX_TRANSPARENT | WS_EX_LAYERED
81+
ctypes.windll.user32.SetWindowLongW(hwnd, GWL_EXSTYLE, style)
82+
ctypes.windll.user32.SetLayeredWindowAttributes(hwnd, 0, 255, 0x00000002)
83+
elif os.name == 'posix': # Linux
84+
self.root.wm_attributes('-type', 'splash')
85+
86+
def main(self):
87+
tk.mainloop()
88+
89+
def new_toast(self, toast=ADVANCEMENT, image_path=None, text1="一个弹窗", color1="yellow", text2="MCToast示例", color2="white",event=None):
90+
"""弹出Toast,但是阻塞"""
91+
global toasts
92+
while True:
93+
for i in range(5):
94+
if toasts[i] == None:
95+
# 使用 Pillow 生成图片
96+
photo=generate_image(toast, image_path, text1, color1, text2, color2)
97+
self.root.deiconify()
98+
toasts[i] = self.canvas.create_image(320, i*64, anchor="nw", image=photo)
99+
event.set()
100+
x=320
101+
speed=-1.96
102+
while x>0:
103+
x+=speed
104+
self.canvas.move(toasts[i], speed, 0)
105+
if speed<-0.1:
106+
speed+=0.006
107+
self.canvas.update()
108+
time.sleep(0.0025)
109+
self.canvas.move(toasts[i], 0, 0)
110+
x=0
111+
speed=0.1
112+
time.sleep(2.5)
113+
while x<320:
114+
x+=speed
115+
self.canvas.move(toasts[i], speed, 0)
116+
if speed<2:
117+
speed+=0.006
118+
self.canvas.update()
119+
time.sleep(0.0025)
120+
self.canvas.delete(toasts[i])
121+
toasts[i] = None
122+
if toasts==[None,None,None,None,None]:
123+
self.root.withdraw()
124+
return
125+
time.sleep(0.2)
126+
127+
def wait_no_toast(self):
128+
"""等待所有Toast消失"""
129+
while True:
130+
if all(toast is None for toast in toasts):
131+
return
132+
time.sleep(0.2)
133+
134+
def stop(self):
135+
self.root.destroy()
136+
137+
def set_no_focus(self):
138+
"""设置窗口为无焦点窗口"""
139+
import ctypes
140+
if os.name == 'nt': # Windows
141+
GWL_EXSTYLE = -20
142+
WS_EX_NOACTIVATE = 0x08000000
143+
hwnd = ctypes.windll.user32.GetParent(self.root.winfo_id())
144+
style = ctypes.windll.user32.GetWindowLongW(hwnd, GWL_EXSTYLE)
145+
style = style | WS_EX_NOACTIVATE
146+
ctypes.windll.user32.SetWindowLongW(hwnd, GWL_EXSTYLE, style)
147+
elif os.name == 'posix': # Linux
148+
self.root.wm_attributes('-type', 'splash')
149+
150+
window=None
151+
def _init():
152+
global window
153+
window=ToastWindowUI()
154+
window.main()
155+
156+
def init():
157+
thread.start_new_thread(_init,())
158+
while type(window)!=ToastWindowUI:
159+
pass
160+
161+
def new_toast(toast=ADVANCEMENT, image_path=None, text1="一个弹窗", color1="yellow", text2="MCToast示例", color2="white"):
162+
global window
163+
#thread.start_new_thread(window.new_toast,(toast, image_path, text1, color1, text2, color2))
164+
#window.new_toast(toast, image_path, text1, color1, text2, color2)
165+
e=Event()
166+
t=Thread(target=window.new_toast,args=(toast, image_path, text1, color1, text2, color2, e))
167+
t.start()
168+
e.wait()
169+
170+
def quit():
171+
global window
172+
window.stop()
173+
174+
def wait_no_toast():
175+
global window
176+
window.wait_no_toast()
177+
178+
if __name__ == "__main__":
179+
# demo
180+
init()
181+
for i in range(1,11):
182+
new_toast(toast=SYSTEM, text2=f"第{i}")
183+
time.sleep(0.5)
184+
wait_no_toast()

mctoast.ui

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?xml version='1.0' encoding='utf-8'?>
2+
<interface version="1.4" author="PygubuDesigner 0.40">
3+
<project>
4+
<settings>
5+
<setting id="name">mctoast</setting>
6+
<setting id="description"> </setting>
7+
<setting id="module_name">mctoast</setting>
8+
<setting id="template">codescript</setting>
9+
<setting id="main_widget">root</setting>
10+
<setting id="main_classname">ToastWindow</setting>
11+
<setting id="main_menu" />
12+
<setting id="output_dir" />
13+
<setting id="output_dir2" />
14+
<setting id="import_tkvariables">False</setting>
15+
<setting id="use_ttk_styledefinition_file">False</setting>
16+
<setting id="use_i18n">False</setting>
17+
<setting id="all_ids_attributes">False</setting>
18+
<setting id="generate_code_onsave">False</setting>
19+
<setting id="use_window_centering_code">False</setting>
20+
<setting id="ttk_style_definition_file" />
21+
</settings>
22+
<customwidgets />
23+
</project>
24+
<object class="tk.Tk" id="root" named="True">
25+
<property name="background">#000000</property>
26+
<property name="borderwidth">0</property>
27+
<property name="geometry">320x64</property>
28+
<property name="height">200</property>
29+
<property name="overrideredirect">true</property>
30+
<property name="resizable">none</property>
31+
<property name="takefocus">false</property>
32+
<property name="width">200</property>
33+
<child>
34+
<object class="tk.Label" id="background" named="True">
35+
<property name="background">#000000</property>
36+
<property name="image">advancement.png</property>
37+
<layout manager="place">
38+
<property name="anchor">nw</property>
39+
<property name="height">64</property>
40+
<property name="width">320</property>
41+
<property name="x">0</property>
42+
<property name="y">0</property>
43+
</layout>
44+
</object>
45+
</child>
46+
</object>
47+
</interface>

0 commit comments

Comments
 (0)