Python3.12自制GUI工具
背景
利用空闲时间写了个GUI工具,实现ts文件转换成mp4文件。
开发环境
python3.12
PyCharm 2024.3.4(Community Edition)
ffmpeg version 2024-01-04-git-33698ef891-essentials_build
完成功能:
待添加功能:
效果图

GUI代码实现
import logging
from tkinter import Tk, Text
from tkinter import filedialog, messagebox, Menu
from tkinter import DISABLED
import os
import re
from pathlib import Path
class GUITools(object):
def __init__(self):
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s %(levelname)s - %(message)s')
self._logger = logging.getLogger(__name__)
self._convert_list = []
def add_log_hander(self, handler):
self._logger.addHandler(handler)
def open_file(self):
filename = filedialog.askopenfilename()
if filename:
self._logger.info("open file {}".format(filename))
def save_file(self):
filename = filedialog.asksaveasfilename()
if filename:
self._logger.info("save file {}".format(filename))
@classmethod
def show_about(cls):
messagebox.showinfo("About", "This is the About Dialog")
def convert(self):
file_name = filedialog.askopenfilename()
if file_name is None:
self._logger.error("file not found")
return
if file_name.endswith('.mp4'):
self._logger.warning("mp4 no need to convert")
elif file_name.endswith('.ts'):
self._logger.info("begin convert ts to mp4")
self._convert_list.append(file_name)
self._convert_list = list(set(self._convert_list))
self._run_ffmpeg_with_output(file_name)
else:
self._logger.error("file type not supported")
def _process_chinese_filename(self, filename):
pattern = re.compile(r'[\u4e00-\u9fff]')
if not bool(pattern.search(filename)):
self._logger.info("not found chinese")
else:
self._logger.info("found chinese")
def _run_ffmpeg_with_output(self, file_name):
new_file_name = Path(file_name).with_suffix('.mp4')
if os.path.isfile(new_file_name):
self._logger.warning("{} already exist, no need convert".format(new_file_name))
return
self._process_chinese_filename(file_name)
cmd = 'ffmpeg -i {} -acodec copy -vcodec copy -f mp4 {}'.format(file_name, new_file_name)
with os.popen(cmd, "r") as f:
for line in f.readlines():
self._logger.info(line)
self._convert_list.append(file_name)
self._convert_list = list(set(self._convert_list))
def delete_ts(self):
for f in self._convert_list:
if f.endswith('.ts') and os.path.isfile(f):
self._logger.info('remove {}'.format(f))
os.remove(f)
def log(self, level, msg):
if level == logging.INFO:
self._logger.info(msg)
elif level == logging.WARNING:
self._logger.warning(msg)
elif level == logging.ERROR:
self._logger.error(msg)
elif level == logging.DEBUG:
self._logger.debug(msg)
elif level == logging.CRITICAL:
self._logger.critical(msg)
class TextBoxHandler(logging.Handler):
def __init__(self, textbox):
logging.Handler.__init__(self)
self.text_box = textbox
def emit(self, record):
msg = self.format(record)
self.text_box.insert("end", msg + '\n')
def clear_log(self):
print('clear log ...')
self.text_box.delete("0.0", "end")
class App(object):
def __init__(self, gui_tool):
self._main_win = Tk()
self._textbox_handler = None
self._gui_tool = gui_tool
self._main_win.title("GUI Menu")
self._main_win.resizable(width=False, height=False)
self._main_win.geometry("640x480")
text_box = Text(self._main_win)
text_box.pack()
self._textbox_handler = TextBoxHandler(text_box)
self._gui_tool.add_log_hander(self._textbox_handler)
menu_bar = Menu(self._main_win)
file_menu = Menu(menu_bar, tearoff=0)
file_menu.add_command(label="Open", command=self._gui_tool.open_file, accelerator="Ctrl+O")
file_menu.add_command(label="Save", command=self._gui_tool.save_file, accelerator="Ctrl+S")
file_menu.add_separator()
file_menu.add_command(label="Exit", command=self._main_win.destroy, accelerator="Ctrl+Q")
menu_bar.add_cascade(label="File", menu=file_menu)
edit_menu = Menu(menu_bar, tearoff=0)
edit_menu.add_command(label="Undo", command=lambda: print("Undo ..."), state=DISABLED)
edit_menu.add_separator()
edit_menu.add_command(label="Copy", command=lambda: print("Copy ..."))
edit_menu.add_command(label="Paste", command=lambda: print("Paste ..."))
menu_bar.add_cascade(label="Edit", menu=edit_menu)
convert_menu = Menu(menu_bar, tearoff=0)
convert_menu.add_command(label="Convert TS to MP4", command=self._gui_tool.convert)
menu_bar.add_cascade(label="Convert", menu=convert_menu)
tool_menu = Menu(menu_bar, tearoff=0)
tool_menu.add_command(label="Clear Log", command=self._textbox_handler.clear_log)
tool_menu.add_command(label="Delete TS", command=self._gui_tool.delete_ts)
menu_bar.add_cascade(label='Tool', menu=tool_menu)
help_menu = Menu(menu_bar, tearoff=0)
help_menu.add_command(label="Help", command=lambda: print("Help Documents"))
help_menu.add_command(label="About", command=GUITools.show_about, accelerator="Ctrl+A")
menu_bar.add_cascade(label="Help", menu=help_menu)
self._main_win.bind("<Control-o>", lambda event: self._gui_tool.open_file())
self._main_win.bind("<Control-s>", lambda event: self._gui_tool.save_file())
self._main_win.bind("<Control-q>", lambda event: self._main_win.destroy())
self._main_win.bind("<Control-a>", lambda event: GUITools.show_about())
self._main_win.config(menu=menu_bar)
def run(self):
self._main_win.mainloop()
def main():
tools = GUITools()
app = App(tools)
app.run()
if __name__ == '__main__':
main()

浙公网安备 33010602011771号