当前位置: 首页> 新闻> 资讯 > 濉溪县最新通告今天_北京小程序制作公司_搜索引擎营销的方式_西安企业网站seo

濉溪县最新通告今天_北京小程序制作公司_搜索引擎营销的方式_西安企业网站seo

时间:2025/9/10 3:31:57来源:https://blog.csdn.net/Clay_K/article/details/146908723 浏览次数:0次
濉溪县最新通告今天_北京小程序制作公司_搜索引擎营销的方式_西安企业网站seo

打造高效集成工具箱:基于Python与Tkinter的实战开发教程

1.概述

在日常的开发和使用中,我们经常需要借助各种小工具来提高工作效率,例如快速启动常用的应用程序、管理文件等。一个简单但功能强大的集成工具箱可以帮助用户快速访问、启动并管理程序。今天,我们将以Python为基础,结合Tkinter和Win32API,开发一个类似Windows快捷方式的工具箱应用,能够让你轻松集成各种常用程序并一键启动。

本文将深入讲解如何使用Tkinter构建图形化界面,如何通过Win32API提取程序图标,以及如何利用Python的强大功能来实现一个简单高效的集成工具箱。通过这个教程,你不仅能了解如何设计和开发图形化应用,还能学习如何高效地处理文件和图标,提升开发技巧。

2.功能解析

2.1. 自动获取当前程序路径

首先,代码中定义了一个get_current_path函数,用来自动获取当前运行程序的路径。无论是在开发环境中运行脚本,还是将程序打包成exe文件后运行,get_current_path都能确保正确获取到当前程序的目录路径。

def get_current_path():"""自动获取当前程序路径的通用方法"""try:# 打包后的情况if getattr(sys, 'frozen', False):return os.path.dirname(sys.executable)  # 返回EXE所在目录# 开发环境return os.path.dirname(os.path.abspath(__file__))  # 返回脚本所在目录except Exception as e:print(f"路径获取失败: {e}")return os.getcwd()  # 退回当前工作目录

2.2. 从程序文件提取图标

get_exe_icon函数是本程序的一个亮点,它能够提取指定可执行文件的图标,并将其转换为可以在Tkinter界面上显示的格式。通过win32gui和win32ui模块,我们可以从exe文件中提取图标并通过PIL库进行处理。

def get_exe_icon(exe_path):"""从exe文件中提取图标"""try:large, small = win32gui.ExtractIconEx(exe_path, 0)win32gui.DestroyIcon(small[0])hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))hbmp = win32ui.CreateBitmap()hbmp.CreateCompatibleBitmap(hdc, 32, 32)hdc = hdc.CreateCompatibleDC()hdc.SelectObject(hbmp)hdc.DrawIcon((0, 0), large[0])bmpinfo = hbmp.GetInfo()bmpstr = hbmp.GetBitmapBits(True)img = Image.frombuffer('RGBA', (bmpinfo['bmWidth'], bmpinfo['bmHeight']), bmpstr, 'raw', 'BGRA', 0, 1)return imgexcept Exception as e:print(f"提取图标失败: {e}")return None

2.3. 程序分类与展示

为了方便管理程序,我们通过分类将程序分组,并在界面上以按钮的形式展示。每个程序按钮都包含一个图标和程序名称,点击按钮即可启动对应程序。程序面板和分类面板分别在左侧和右侧布局,通过ttk.Button实现按钮的创建,并使用UniformButton自定义按钮样式,以保证按钮的统一尺寸和良好的用户体验。

def create_category_panel(self):"""分类面板(宽度99)"""self.category_frame = ttk.Frame(self.main_frame, width=99)self.category_frame.pack(side=tk.LEFT, fill=tk.Y, padx=3)self.category_canvas = tk.Canvas(self.category_frame, width=99, highlightthickness=0)scrollbar = ttk.Scrollbar(self.category_frame, orient="vertical", command=self.category_canvas.yview)self.category_container = ttk.Frame(self.category_canvas)

2.4. 程序扫描与动态加载

scan_directory方法用于扫描当前目录下的所有程序文件,并将其按照类别分组。程序支持多种文件类型,如.exe、.bat、.cmd和.lnk。在扫描完成后,程序将动态加载到界面上,用户可以通过点击不同的类别查看对应的程序。

def scan_directory(self):"""扫描目录"""self.categories = {"所有程序": []}executable_ext = ['.exe', '.bat', '.cmd', '.lnk']for item in os.listdir(self.current_dir):path = os.path.join(self.current_dir, item)if os.path.isdir(path):self.categories[item] = []for root, _, files in os.walk(path):for file in files:if os.path.splitext(file)[1].lower() in executable_ext:full_path = os.path.join(root, file)self.categories[item].append({"name": os.path.splitext(file)[0],"path": full_path})self.categories["所有程序"].append({"name": os.path.splitext(file)[0],"path": full_path})else:if os.path.splitext(item)[1].lower() in executable_ext:self.categories["所有程序"].append({"name": os.path.splitext(item)[0],"path": path})

2.5. 程序启动功能

通过launch_program方法,我们可以启动用户点击的程序。该方法使用subprocess.Popen来调用外部程序。对于文件路径中的空格,代码使用了引号确保路径能够正确解析。

def launch_program(self, path):"""启动程序"""try:subprocess.Popen(f'"{path}"', shell=True)except Exception as _e:print(f"启动失败: {_e}")

2.6. 用户界面设计

程序的UI界面设计简洁而直观,使用Tkinter创建了一个分为左右两部分的布局。左侧为程序分类面板,右侧为程序展示面板。用户可以通过点击左侧的按钮切换不同的程序类别。

此外,每个程序按钮都拥有统一的尺寸、图标和文本显示,点击按钮后会高亮显示。按钮的样式通过自定义UniformButton类来实现,使得每个按钮都保持一致的外观和操作响应。

class UniformButton(tk.Frame):"""统一尺寸的程序按钮组件"""def __init__(self, parent, text, image, command):super().__init__(parent, bg="white", highlightthickness=0)self.button_width = 70self.button_height = 90self.max_chars = 10self.max_lines = 2

3. 效果展示:

在这里插入图片描述

4. 相关源码:

import os
import sys
import tkinter as tk
from tkinter import ttk
import win32ui
import win32gui
from PIL import Image, ImageTk
import subprocess
from win32com.client import Dispatchdef get_current_path():"""自动获取当前程序路径的通用方法"""try:# 打包后的情况if getattr(sys, 'frozen', False):return os.path.dirname(sys.executable)  # 返回EXE所在目录# 开发环境return os.path.dirname(os.path.abspath(__file__))  # 返回脚本所在目录except Exception as e:print(f"路径获取失败: {e}")return os.getcwd()  # 退回当前工作目录def get_exe_icon(exe_path):"""从exe文件中提取图标"""try:# 提取图标large, small = win32gui.ExtractIconEx(exe_path, 0)win32gui.DestroyIcon(small[0])# 创建设备上下文hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))hbmp = win32ui.CreateBitmap()hbmp.CreateCompatibleBitmap(hdc, 32, 32)# 在设备上下文中绘制图标hdc = hdc.CreateCompatibleDC()hdc.SelectObject(hbmp)hdc.DrawIcon((0, 0), large[0])# 获取位图信息和位图数据bmpinfo = hbmp.GetInfo()bmpstr = hbmp.GetBitmapBits(True)# 创建PIL图像对象img = Image.frombuffer('RGBA',(bmpinfo['bmWidth'], bmpinfo['bmHeight']),bmpstr, 'raw', 'BGRA', 0, 1)return imgexcept Exception as e:print(f"提取图标失败: {e}")return Noneclass UniformButton(tk.Frame):"""统一尺寸的程序按钮组件"""def __init__(self, parent, text, image, command):super().__init__(parent, bg="white", highlightthickness=0)# 固定按钮尺寸self.button_width = 70self.button_height = 90self.max_chars = 10self.max_lines = 2self.config(width=self.button_width, height=self.button_height)self.pack_propagate(False)# 主容器self.content_frame = tk.Frame(self, bg="white")self.content_frame.pack(fill=tk.BOTH, expand=True)# 图标区域self.icon_label = tk.Label(self.content_frame, image=image, bg="white",borderwidth=0)self.icon_label.image = imageself.icon_label.pack(pady=(5, 2), expand=True)# 文本区域processed_text = self.process_text(text)self.text_label = tk.Label(self.content_frame, text=processed_text,wraplength=self.button_width-15,justify="center",font=("微软雅黑", 8),bg="white",borderwidth=0)self.text_label.pack(pady=(0, 5))# 事件绑定self.bind_all_children("<Button-1>", lambda e: command())self.bind("<Enter>", self.on_enter)self.bind("<Leave>", self.on_leave)def bind_all_children(self, event, handler):for child in self.winfo_children():child.bind(event, handler)if isinstance(child, tk.Frame):for subchild in child.winfo_children():subchild.bind(event, handler)def process_text(self, text):text = text[:20]words = text.split()lines = []current_line = []for word in words:if len(word) > self.max_chars:chunks = [word[i:i+self.max_chars] for i in range(0, len(word), self.max_chars)]current_line.extend(chunks)else:current_line.append(word)if sum(len(w) for w in current_line) + (len(current_line)-1) > self.max_chars:lines.append(" ".join(current_line[:-1]))current_line = [current_line[-1]]if len(lines) >= self.max_lines:breakif current_line and len(lines) < self.max_lines:lines.append(" ".join(current_line))return "\n".join(lines[:self.max_lines]) + ("..." if len(text) > 20 else "")def on_enter(self, event):  # pylint: disable=unused-argumentself.config(bg="#e0e0e0")self.content_frame.config(bg="#e0e0e0")for child in self.content_frame.winfo_children():child.config(bg="#e0e0e0")def on_leave(self, event):  # pylint: disable=unused-argumentself.config(bg="white")self.content_frame.config(bg="white")for child in self.content_frame.winfo_children():child.config(bg="white")class AppLauncher:def __init__(self, root):self.root = rootself.root.title("程序启动器")self.root.geometry("530x400")self.root.resizable(False, False)self.icon_size = 32# 设置窗口图标self.set_window_icon()# 主界面self.main_frame = ttk.Frame(root)self.main_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)# 初始化默认图标self.default_icon = self.get_default_icon()# 组件初始化self.create_category_panel()self.create_program_panel()# 数据初始化self.current_dir = get_current_path()  # 使用通用路径获取方法self.scan_directory()self.populate_categories()self.show_category("所有程序")def set_window_icon(self):"""设置窗口图标"""try:# 使用与编译后的exe相同的图标exe_path = sys.executableicon_img = get_exe_icon(exe_path)if icon_img:icon_img.save('temp_icon.ico', 'ICO')self.root.iconbitmap('temp_icon.ico')os.remove('temp_icon.ico')else:print("无法提取exe图标,使用默认图标")self.root.iconbitmap('icon/app.ico')except Exception as e:print(f"设置窗口图标失败: {e}")def resolve_shortcut(self, path):"""解析快捷方式"""try:shell = Dispatch('WScript.Shell')shortcut = shell.CreateShortCut(path)return shortcut.TargetPathexcept Exception as _e:print(f"快捷方式解析失败: {path}")return Nonedef get_program_icon(self, path):"""增强图标获取"""try:# 处理快捷方式if path.lower().endswith('.lnk'):target = self.resolve_shortcut(path)if target and os.path.exists(target):path = target# 获取图标large, _ = win32gui.ExtractIconEx(path, 0)if not large:raise Exception("No icons found")hicon = large[0]hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))hbmp = win32ui.CreateBitmap()hbmp.CreateCompatibleBitmap(hdc, self.icon_size, self.icon_size)hdc = hdc.CreateCompatibleDC()hdc.SelectObject(hbmp)hdc.DrawIcon((0, 0), hicon)bmpstr = hbmp.GetBitmapBits(True)img = Image.frombuffer('RGBA', (self.icon_size, self.icon_size), bmpstr, 'raw', 'BGRA', 0, 1)return ImageTk.PhotoImage(img)except Exception as _e:  print(f"图标加载失败: {os.path.basename(path)}")return self.default_icondef get_default_icon(self):"""系统默认图标"""try:# 使用文件夹图标shell32 = "C:\\Windows\\System32\\shell32.dll"large, _ = win32gui.ExtractIconEx(shell32, 3)hicon = large[0]hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))hbmp = win32ui.CreateBitmap()hbmp.CreateCompatibleBitmap(hdc, self.icon_size, self.icon_size)hdc = hdc.CreateCompatibleDC()hdc.SelectObject(hbmp)hdc.DrawIcon((0, 0), hicon)bmpstr = hbmp.GetBitmapBits(True)img = Image.frombuffer('RGBA', (self.icon_size, self.icon_size),bmpstr, 'raw', 'BGRA', 0, 1)return ImageTk.PhotoImage(img)except Exception as _e:  print(f"默认图标加载失败: {_e}")return ImageTk.PhotoImage(Image.new('RGBA', (self.icon_size, self.icon_size), (240, 240, 240)))def create_category_panel(self):"""分类面板(宽度99)"""self.category_frame = ttk.Frame(self.main_frame, width=99)self.category_frame.pack(side=tk.LEFT, fill=tk.Y, padx=3)self.category_canvas = tk.Canvas(self.category_frame, width=99,highlightthickness=0)scrollbar = ttk.Scrollbar(self.category_frame, orient="vertical", command=self.category_canvas.yview)self.category_container = ttk.Frame(self.category_canvas)self.category_container.bind("<Configure>", lambda e: self.category_canvas.configure(scrollregion=self.category_canvas.bbox("all"),width=99))self.category_canvas.create_window((0,0), window=self.category_container, anchor="nw",width=99)self.category_canvas.configure(yscrollcommand=scrollbar.set)self.category_canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)scrollbar.pack(side=tk.RIGHT, fill=tk.Y)ttk.Label(self.category_container, text="应用分类", font=("微软雅黑", 9),padding=3).pack(pady=5)def create_program_panel(self):"""程序显示面板"""self.program_frame = ttk.Frame(self.main_frame)self.program_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)self.program_canvas = tk.Canvas(self.program_frame, highlightthickness=0)scrollbar = ttk.Scrollbar(self.program_frame, orient="vertical", command=self.program_canvas.yview)self.program_container = ttk.Frame(self.program_canvas)self.program_container.bind("<Configure>", lambda e: self.program_canvas.configure(scrollregion=self.program_canvas.bbox("all")))self.program_canvas.create_window((0,0), window=self.program_container, anchor="nw")self.program_canvas.configure(yscrollcommand=scrollbar.set)self.program_canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)scrollbar.pack(side=tk.RIGHT, fill=tk.Y)def scan_directory(self):"""扫描目录"""self.categories = {"所有程序": []}executable_ext = ['.exe', '.bat', '.cmd', '.lnk']for item in os.listdir(self.current_dir):path = os.path.join(self.current_dir, item)if os.path.isdir(path):self.categories[item] = []for root, _, files in os.walk(path):for file in files:if os.path.splitext(file)[1].lower() in executable_ext:full_path = os.path.join(root, file)self.categories[item].append({"name": os.path.splitext(file)[0],"path": full_path})self.categories["所有程序"].append({"name": os.path.splitext(file)[0],"path": full_path})else:if os.path.splitext(item)[1].lower() in executable_ext:self.categories["所有程序"].append({"name": os.path.splitext(item)[0],"path": path})def populate_categories(self):"""填充分类"""for category in self.categories.keys():btn = ttk.Button(self.category_container,text=category,command=lambda c=category: self.show_category(c),width=12)btn.pack(fill=tk.X, padx=2, pady=2)def show_category(self, category):"""显示分类"""for widget in self.program_container.winfo_children():widget.destroy()programs = self.categories.get(category, [])if not programs:ttk.Label(self.program_container, text="该分类暂无应用").pack(pady=50)returnmax_columns = 5row = col = 0for idx, program in enumerate(programs):col = idx % max_columnsrow = idx // max_columnsbutton = UniformButton(parent=self.program_container,text=program["name"],image=self.get_program_icon(program["path"]),command=lambda p=program["path"]: self.launch_program(p))button.grid(row=row, column=col, padx=3, pady=3, sticky="nsew")self.program_container.grid_columnconfigure(col, weight=1)self.program_container.grid_rowconfigure(row, weight=1)def launch_program(self, path):"""启动程序"""try:subprocess.Popen(f'"{path}"', shell=True)except Exception as _e:  print(f"启动失败: {_e}")if __name__ == "__main__":root_window = tk.Tk()  style = ttk.Style()style.configure("TButton", padding=3, font=("微软雅黑", 8),width=12)style.map("TButton",background=[('active', '#f0f0f0')])AppLauncher(root_window)root_window.mainloop()

5. 总结:

通过本文的介绍,我们使用Python实现了一个集成工具箱应用,涵盖了从程序路径获取、图标提取到程序分类展示和启动等多个功能模块。这个工具不仅能帮助用户轻松管理并启动程序,还具备了良好的用户体验。通过使用Tkinter和Win32API,我们可以创建一个强大且易于扩展的应用,帮助提升工作效率。

如果你对这个项目感兴趣,可以根据自己的需求进一步优化和扩展功能,例如支持更多类型的程序文件、改进图标展示、增加搜索和排序功能等。希望通过本文的示例,你能深入理解如何利用Python构建桌面应用,提升你的开发技能。

关键字:濉溪县最新通告今天_北京小程序制作公司_搜索引擎营销的方式_西安企业网站seo

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: