前言
用python实现一个无边框的阅读小工具。
python版本 3.7 和 3.10 均已验证
阅读本文收获
- 如何用 tkinter 开发一个无边框窗体,并可以通过鼠标拖动窗口
- 无边框窗体,如何通过 Sizegrip 控件调整窗体大小
- 实现老板键功能,并一键唤起隐藏
- 通过 Menu 控件实现右键菜单功能
- 通过 bind 绑定事件实现快捷键调节透明度和字体大小
源码
import ctypes
import tkinter as tk
from tkinter.filedialog import *
from tkinter.font import Font
from tkinter.scrolledtext import ScrolledText
import _thread
import win32con
import ctypes.wintypes
from tkinter import ttk
import sys
def register():
#注册全局热键
HOTKEYS = [
{"keys": (win32con.VK_F3, win32con.MOD_WIN), "command": handle_win_f3},
{"keys": (win32con.VK_F4, win32con.MOD_WIN), "command": handle_win_f4},
]
for i, h in enumerate(HOTKEYS):
vk, modifiers = h["keys"]
ctypes.windll.user32.RegisterHotKey(None, i, modifiers, vk)
try:
msg = ctypes.wintypes.MSG()
while ctypes.windll.user32.GetMessageA(ctypes.byref(msg), None, 0, 0) != 0:
if msg.message == win32con.WM_HOTKEY:
HOTKEYS[msg.wParam]["command"]()
ctypes.windll.user32.TranslateMessage(ctypes.byref(msg))
ctypes.windll.user32.DispatchMessageA(ctypes.byref(msg))
finally:
for i, h in enumerate(HOTKEYS):
ctypes.windll.user32.UnregisterHotKey(None, i)
#注册全局热键
def handle_win_f3():
app.update()
app.deiconify()
def handle_win_f4():
app.withdraw()
x, y = 0, 0
def mouse_motion(event):
if event.widget.widgetName == 'scrollbar':
return
if event.widget.widgetName == 'ttk::sizegrip':
return
global x, y
offset_x, offset_y = event.x - x, event.y - y
new_x = app.winfo_x() + offset_x
new_y = app.winfo_y() + offset_y
app.geometry(f"+{new_x}+{new_y}")
def mouse_press( event):
global x, y
x, y = event.x, event.y
def changeHotkey(event):
alpha = app.attributes("-alpha")
if float(alpha) - 0.1 < 0.1:
return
app.attributes("-alpha", float(alpha) - 0.1)
def changeHotkey1(event):
alpha = app.attributes("-alpha")
if float(alpha) + 0.1 > 1:
return
app.attributes("-alpha", float(alpha) + 0.1)
def openNovel():
filename = askopenfilename(title="选择文件", filetypes=[('执行文件','.txt'),('执行文件','.log'),('执行文件','.csv')])
with open(filename, encoding='utf8') as file:
content=file.read()
wordText.delete("1.0", tk.END)
wordText.insert(tk.END, content.rstrip())
def openDescribe():
win= tk.Toplevel()
win.title("老余阅读器说明v1.1")
win.geometry("500x300+10+10")
tk.Label(win, text='支持csv,log,txt格式的文件,底部可调节窗体大小').grid(row=0, column=1)
tk.Label(win, text='ctrl + 滚轮 调整字体大小').grid(row=1, column=1)
tk.Label(win, text='ctrl + [ 增加透明度 ').grid(row=2, column=1)
tk.Label(win, text='ctrl + ] 减少透明度 ').grid(row=3, column=1)
tk.Label(win, text='老板键唤起:win + F3 ').grid(row=4, column=1)
tk.Label(win, text='老板键隐藏:win + F4 ').grid(row=5, column=1)
win.mainloop()
def exit():
sys.exit()
def openMenu(event):
popup_menu.post(event.x_root, event.y_root)
def mouseJudgeSize(event):
if event.delta > 0:
my_font["size"] = my_font["size"] + 1
else:
my_font["size"] = my_font["size"] - 1
def OnMotion(event):
x1 = app.winfo_pointerx()
y1 = app.winfo_pointery()
x0 = app.winfo_rootx()
y0 = app.winfo_rooty()
app.geometry("%sx%s" % ((x1-x0),(y1-y0)))
app = tk.Tk()
app.geometry('800x400')
app.attributes("-alpha", 1) #透明度
app.overrideredirect(True) #tk无边框
app.update()
#绑定鼠标拖动事件
app.bind("<B1-Motion>", mouse_motion)
app.bind("<Button-1>", mouse_press)
#为了能够快捷键调整文本大小
my_font = Font(family="Consolas", size=12)
#拖动大小控件
grip = ttk.Sizegrip(app)
grip.pack(side='bottom', fill=tk.X)
grip.bind("<B1-Motion>", OnMotion)
#滚动文本框
wordText = ScrolledText(app, font=my_font)
wordText.pack(fill=tk.BOTH, expand=True)
wordText.bind('<Button-3>', openMenu)
wordText.bind('<Control-MouseWheel>', mouseJudgeSize)
#右键菜单
popup_menu = tk.Menu(app, tearoff = 0)
popup_menu.add_command(label="打开", command=openNovel)
popup_menu.add_command(label="介绍", command=openDescribe)
popup_menu.add_command(label="退出", command=exit)
#绑定透明度调节的快捷键
app.bind("<Control-[>", changeHotkey)
app.bind("<Control-]>", changeHotkey1)
_thread.start_new_thread(register, ())
app.mainloop()
Python 系列:
读取文件 – 使用 python 读取 xls,xlsx,csv,doc,docx,pdf 格式的文件
阅读小工具 – 使用 python 开发无边框窗体阅读小工具
操作xlsx文件 – 使用 openpyxl 技术对 xlsx 的各种操作
前端系列:
扫雷游戏 – JavaScript 仿造 windows 编写 扫雷游戏
前端工具库 xlsx 处理表头合并 – 如何使用 xlsx 技术处理复杂的表头合并
CSS 布局技巧 – 对整体布局的心得体会
NVM Node 多版本控制教程 – Node 版本控制神器 NVM
Spring 系列:
Spring部署 – Spring 的多种 linux 部署方式
Spring实现策略模式 – 通过 Spring 实现多种策略模式