# -*- encoding: utf-8 -*- """ @File : test2.py @License : (C)Copyright 2018-2022 @Modify Time @Author @Version @Description ------------ ------- -------- ----------- 2023/8/21 13:45 zart20 1.0 None """ import re import tkinter as tk from tkinter import scrolledtext from math import sin, cos, pi import numpy as np from PIL import Image, ImageTk import read_bin from files_sys_sim import * file_name_set = set() # 文件项的唯一集合 blocks_label_set = set() # 文件标签的唯一集合 def find_missing_and_duplicates(lst): print("列表长度:", len(lst)) expected_set = set(range(1, 100)) input_set = set(lst) print("转换集合长度:", len(input_set)) missing_numbers = list(expected_set - input_set) duplicate_numbers = list(input_set.intersection(expected_set)) print("缺失的数字:", missing_numbers) print("重复的数字:", duplicate_numbers) return missing_numbers, duplicate_numbers def get_unique_tag(): # 获取唯一字母标签 for ascii_code in range(65, 91): character = chr(ascii_code) if character not in blocks_label_set: blocks_label_set.add(character) return character def set_canvas_size(foreground_image, up_or_down=None): # 调整前景 new_width = 555 # 新的宽度 if up_or_down == "up": new_height = 245 # 新的高度 else: new_height = 555 # 新的高度 foreground_image = foreground_image.resize((new_width, new_height), Image.LANCZOS) foreground_photo = ImageTk.PhotoImage(foreground_image) return foreground_photo class InterfaceFile: def __init__(self, root: tk.Tk): self.current_step = None self.file_modi_tag = False # 文件修改状态 self.massages = [] # 系统消息队列 self.sim_fat_copy = None # 仿真FAT表复制临时列表,用于校验 self.sim_file_copy = None # 仿真文件复制临时列表,用于校验 self.ex_disk_oc = True # 交替显示保存占用和添加占用标志 self.ex_disk_la = True # 修改保存标签和清除标签的标志 self.sim_disk_copy = None # 磁盘复制临时列表,用于校验 self.block_modi_tag = False # 磁盘块修改标志置否 self.block_modi_lb = None # 磁盘块标签值初始化 self.old_key = None # FAT表上一次的记录值 self.fat_modi_num = None # 打开下一个FAT单元格之前的修改数值 self.fat_modi_tag = False # 修改状态标签,为True时进入修改状态 self.clear_tag = True # 清除标签,让标签清理和fat清理操作互斥 self.check = None # 检查磁盘条件 self.code = None # 当前磁盘块标签字母 self.creating = True # 正在创建的状态 self.SimFAT = initialize_simfat() # SimFAT 表初始化 self.SimDisk = initialize_simdisk() # SimDisk 区域初始 self.FolderItems = [] # 文件项储存 self.fat_unique_set = {0} # fat表去重集合,防止在一个位置建立多个磁盘块 self.root = root self.canvas_width = 1440 self.canvas_height = 830 # self.root.geometry(f'{self.canvas_width}x{self.canvas_height}+{2100}+{100}') self.root.geometry(f'{self.canvas_width}x{self.canvas_height}') self.root.title("文件系统仿真TK版") self.canvas = tk.Canvas(root, width=self.canvas_width, height=self.canvas_height, bg="white") self.canvas.pack(fill="both", expand=True) self.fat_table_position_mapping = dict() # FAT表位置-序号映射字典 self.blocks_position_mapping = dict() # 磁盘块位置-序号映射字典 # 创建菜单栏 menubar = tk.Menu(self.root, font=("son", 16)) self.root.config(menu=menubar) # 创建文件菜单 file_menu = tk.Menu(menubar, tearoff=0) file_menu.configure(font=("son", 16)) menubar.add_cascade(label="真实磁盘操作", menu=file_menu) # 在文件菜单中添加选项 sector_0 = read_bin.read_sector_0() file_menu.add_command(label="读取磁盘文件0扇区", command=lambda: self.show_real_disk("磁盘0扇区", sector_0)) sector_FAT1_1 = read_bin.read_sector_FAT1() file_menu.add_command(label="读取磁盘文件FAT1", command=lambda: self.show_real_disk("FAT1_0扇区", sector_FAT1_1)) root_path0 = read_bin.read_sector_root_path(0) file_menu.add_command(label="读取根目录0扇区", command=lambda: self.show_real_disk("根目录0扇区", root_path0)) root_path1 = read_bin.read_sector_root_path(1) file_menu.add_command(label="读取根目录1扇区", command=lambda: self.show_real_disk("根目录1扇区", root_path1)) # 创建保存菜单 save_menu = tk.Menu(menubar, tearoff=0) save_menu.configure(font=("son", 16)) menubar.add_cascade(label="手动保存", menu=save_menu) save_menu.add_command(label="开启手动保存模式", command=lambda : self.manual_save()) # 将鼠标左键点击事件绑定到函数on_left_click self.canvas.bind("", self.on_left_click) background_image = Image.open("img/bg2.png") background_image = background_image.resize((1440, 830)) background_photo = ImageTk.PhotoImage(background_image) # 在Canvas上显示背景图片 self.canvas.create_image(0, 0, anchor="nw", image=background_photo) # 载入前景图片 foreground_image_pink = Image.open("img/pink_bg.png") foreground_photo_pink = set_canvas_size(foreground_image_pink, "up") foreground_image_purple = Image.open("img/purple_bg.png") foreground_photo_purple = set_canvas_size(foreground_image_purple, "up") foreground_image_jb = Image.open("img/jade_blue_bg.png") foreground_photo_jb = set_canvas_size(foreground_image_jb) foreground_image_sky_blue = Image.open("img/sky_blue_bg.png") foreground_photo_sky_blue = set_canvas_size(foreground_image_sky_blue) x1, y1, x2, y2 = 1130, 10, 1433, 819 self.canvas_child = tk.Canvas(self.canvas,) self.canvas_child.place(x=x1,y=y1) self.canvas_child.config(width=303, height=809) self.canvas_child.create_rectangle(x1, y1, x2, y2, outline="white", fill="white") # 在Canvas上显示调整后大小的前景图片 self.canvas.create_image(10, 10, anchor="nw", image=foreground_photo_pink) self.canvas.create_image(570, 10, anchor="nw", image=foreground_photo_purple) self.canvas.create_image(10, 265, anchor="nw", image=foreground_photo_jb) self.canvas.create_image(570, 265, anchor="nw", image=foreground_photo_sky_blue) # 保留图片引用以防止垃圾回收 self.canvas.background_image = background_photo self.canvas.foreground_image_pink = foreground_photo_pink self.canvas.foreground_photo_purple = foreground_photo_purple self.canvas.foreground_photo_jb = foreground_photo_jb self.canvas.foreground_photo_sky_blue = foreground_photo_sky_blue # 按键布局 image_create = Image.open("img/创建文件.png") self.photo_create = ImageTk.PhotoImage(image_create) self.set_canvas_button([348, 20], self.photo_create, self.creat_file, bg="#996BC7") image_save = Image.open("img/保存.png") self.photo_save = ImageTk.PhotoImage(image_save) self.file_save_button = self.set_canvas_button([435, 20], self.photo_save, self.save_file, bg="#996BC7") image_query = Image.open("img/查询.png") self.photo_query = ImageTk.PhotoImage(image_query) self.set_canvas_button([495, 20], self.photo_query, self.query_file, bg="#996BC7") image_create_path = Image.open("img/创建目录项.png") self.photo_create_path = ImageTk.PhotoImage(image_create_path) self.creat_path_button = self.set_canvas_button([825, 20], self.photo_create_path, self.creat_path, bg="#785FDA") image_clear_file = Image.open("img/清除目录项.png") self.photo_clear_file = ImageTk.PhotoImage(image_clear_file) self.clear_file_button = self.set_canvas_button([915, 20], self.photo_clear_file, self.clear_file_label, bg="#785FDA") image_check = Image.open("img/文件校验.png") self.photo_check = ImageTk.PhotoImage(image_check) self.file_check_button = self.set_canvas_button([1015,20], self.photo_check, self.file_check) image_reset = Image.open("img/重置.png") self.photo_reset = ImageTk.PhotoImage(image_reset) self.set_canvas_button([1065, 20], self.photo_reset, self.restart, bg="#785FDA") image_fat_check = Image.open("img/校验.png") self.photo_fat_check = ImageTk.PhotoImage(image_fat_check) self.fat_check_button = self.set_canvas_button([165, 274], self.photo_fat_check, self.fat_checkout) image_clear_form = Image.open("img/清除表单项.png") self.photo_clear_form = ImageTk.PhotoImage(image_clear_form) self.set_canvas_button([270, 274], self.photo_clear_form, self.clear_fat_label) image_save_form = Image.open("img/保存表单项.png") self.photo_save_form = ImageTk.PhotoImage(image_save_form) self.set_canvas_button([368, 274], self.photo_save_form, self.modi_fat_save) image_change_form = Image.open("img/修改表单项.png") self.photo_change_form = ImageTk.PhotoImage(image_change_form) self.set_canvas_button([465, 274], self.photo_change_form, self.modi_fat) image_disk_check = Image.open("img/校验2.png") self.photo_disk_check = ImageTk.PhotoImage(image_disk_check) self.disk_check_button = self.set_canvas_button([680, 274], self.photo_disk_check, self.disk_checkout) image_save_occupy = Image.open("img/保存占用.png") self.photo_save_occupy = ImageTk.PhotoImage(image_save_occupy) image_add_occupy = Image.open("img/添加占用.png") self.photo_add_occupy = ImageTk.PhotoImage(image_add_occupy) self.exchange_button_disk_occupy() # 动态按钮函数用于 表示交保存和添加占用 image_revamp_label = Image.open("img/修改标签.png") self.photo_revamp_label = ImageTk.PhotoImage(image_revamp_label) image_save_label = Image.open("img/保存标签.png") self.photo_save_label = ImageTk.PhotoImage(image_save_label) self.exchange_button_disk_label() # 动态标签函数用于 表示交换修改和保存标签 image_clear_label = Image.open("img/清除标签.png") self.photo_clear_label = ImageTk.PhotoImage(image_clear_label) self.set_canvas_button([1040, 274], self.photo_clear_label, self.clear_disk_label) # 设置 self.file_name_label = self.set_canvas_label_entry([20, 21], "输入文件名", 10, [120, 20]) # 设置输入框和输入标签 self.blocks_num_label = self.set_canvas_label_entry([255, 21], "块数", 3, [295, 20]) # 设置输入框和输入标签 self.path_name_label = self.set_canvas_label_entry([580, 21], "文件夹(目录)", 10, [690, 20]) # 设置输入框和输入标签 # 设置canvas_label self.canvas.create_text(20, 275, text="文件分配表FAT", anchor="nw", fill="white", font=("Arial", 14)) self.canvas.create_text(20, 65, text="初始文件模拟区:", anchor="nw", fill="white", font=("Arial", 14)) self.canvas.create_text(580, 275, text="磁盘模块", anchor="nw", fill="white", font=("Arial", 14)) self.canvas.create_text(575, 70, anchor=tk.NW, text="文件名\t首块\t块数\t标签", font=("Arial", 14), fill="white", ) self.canvas_child.create_text(150, 21, text="操作指引", anchor=tk.CENTER, fill="black", font=("son", 14, "bold")) self.canvas_child.create_text(150, 240, text="系统消息", anchor=tk.CENTER, fill="black", font=("son", 14, "bold")) self.photo_fk3 = self.image_transition("img/fk3.png") # 黄色方块,创建文件用 self.photo_fk1 = self.image_transition("img/fk1.png") # 透明位置方块 提供棋盘 self.photo_fk2 = self.image_transition("img/fk2.png") # 灰色方块,代表未选择方块,或者占用方块 # FAT模块 self.draw_fat_line() # 磁盘模块 self.draw_disk_background() # 创建滚动文本框 self.info_text = scrolledtext.ScrolledText(self.canvas_child, wrap=tk.WORD, width=25, height=24) self.info_text.place(x=10,y=265) self.info_text.config(font=("Arial", 14)) self.canvas_child.bind("", self.info_xy) def info_xy(self,event): print(event.x,event.y) def sys_info(self, massage): '''系统消息''' self.info_text.insert("end", massage+"\n") self.info_text.see("end") def special_info(self, s_msg): '''操作指引消息''' self.canvas_child.delete("s_msg") s_msgs = s_msg.split("\n") for i, msg in enumerate(s_msgs): self.canvas_child.create_text(150,60+i*25,text=msg,font=("Arial", 14), anchor=tk.CENTER, tags="s_msg") def exchange_button_disk_label(self): if self.ex_disk_la: self.set_canvas_button([950, 274], self.photo_revamp_label, self.modi_block_lb, tags="prl") else: self.set_canvas_button([950, 274], self.photo_save_label, self.modi_block_save, tags="psl") def exchange_button_disk_occupy(self): if self.ex_disk_oc: self.add_occupy_button = self.set_canvas_button([860, 274], self.photo_add_occupy, self.add_occupy, tags="pao") else: self.set_canvas_button([860, 274], self.photo_save_occupy, self.save_occupy, tags="pso") def set_canvas_label_entry(self, label_pot: list, label_text: str, entry_width: int, entry_pot: list): self.canvas.create_text(label_pot[0], label_pot[1], text=label_text, anchor="nw", fill="white", font=("Arial", 14)) return self.set_canvas_entry(entry_pot[0], entry_pot[1], entry_width, "") def set_canvas_button(self, button_pot: list, button_photo: ImageTk.PhotoImage, command, tags=None, bg="#3E97C1"): button = tk.Button(self.canvas, image=button_photo, command=command, bd=0, relief="raised", highlightthickness=0, compound="center", bg=bg, activebackground=bg) self.canvas.create_window(button_pot, anchor="nw", window=button, tags=tags) return button def set_canvas_entry(self, x, y, entry_width: int, default: str, tags=None, font_size=None): if not font_size: font_size = 16 entry_file_name = tk.Entry(self.root, width=entry_width, ) entry_file_name.configure(font=("Arial", font_size), borderwidth=1, relief="sunken", ) entry_file_name.insert(0, default) self.canvas.create_window(x, y, anchor="nw", window=entry_file_name, tags=tags) return entry_file_name def show_fat(self, row, column, length_side=430): """映射显示FAT表""" tags = "fat_tag" # 定义删除标志 side_half = length_side // 20 # 每行和每列的间隔距离的一半 num = self.SimFAT[row][column] if num != 0: x = self.fat_table_position_mapping[row, column][0] + side_half y = self.fat_table_position_mapping[row, column][1] + side_half self.canvas.create_text(x, y, anchor=tk.CENTER, text=num, font=("Arial", 16), fill="white", tags=tags) def show_all_fat(self): self.canvas.delete("fat_tag") for i in range(10): for n in range(10): self.show_fat(i, n) def load_files_list(self, fat_ls: list[int], block_label="default"): # 直接根据含第一块位置的fat表生成fat和disk显示 # 假设block的去重在数据层面就已经处理好了 self.show_all_disk() # 更新磁盘显示 for i, value in enumerate(fat_ls): row = value // 10 column = value % 10 if block_label == "default": block_label = self.SimDisk[row][column][0] if i < len(fat_ls) - 1: self.SimFAT[row][column] = fat_ls[i + 1] else: self.SimFAT[row][column] = "FF" self.SimDisk[row][column] = f"{block_label}{i + 1}" self.show_disk(row, column, True) # 最后创建颜色才为黄色 self.show_all_fat() # 更新fat表显示 def draw_fat_line(self, left_top_point=(80, 365), length_side=430): """FAT框架显示""" left_x, left_y = left_top_point # 偏移量x和y short_side = length_side // 10 # 每行和每列的间隔距离 for i in range(10): # 坐标映射 for n in range(10): x = short_side * i + left_x y = short_side * n + left_y self.fat_table_position_mapping[n, i] = [x, y] for line in range(11): # 画线 x1, x2 = short_side * line + left_x, left_x y1, y2 = short_side * line + left_y, left_y self.canvas.create_line(x1, left_y, x1, left_y + length_side, fill="white", width=1) self.canvas.create_line(left_x, y1, left_x + length_side, y1, fill="white", width=1) for num in range(10): # 画序号 x, y = short_side * num + left_x + (short_side // 2), short_side * num + left_y + (short_side // 2) self.canvas.create_text(x, left_y - 20, text=f"{num}", font=("Arial", 12), anchor="center", fill="white") self.canvas.create_text(left_x - 20, y, text=f"{num}", font=("Arial", 12), anchor="center", fill="white") return self.fat_table_position_mapping def show_disk(self, row, column, color_tag=None): """映射显示单个磁盘块""" tags = "fat_disk" # 定义删除标志 text = self.SimDisk[row][column] if text != 0: x = self.blocks_position_mapping[row, column][0] + 1 y = self.blocks_position_mapping[row, column][1] + 1 if color_tag: self.draw_blocks(x, y, tags, text, "label_disk", self.photo_fk3) else: self.draw_blocks(x, y, tags, text, "label_disk", self.photo_fk2) def show_all_disk(self): """显示所有磁盘块""" self.canvas.delete("fat_disk") self.canvas.delete("label_disk") for i in range(10): for n in range(10): self.show_disk(i, n) def draw_disk_background(self, left_top_point=(650, 365), length_side=430): """创建磁盘块图例,并返回每个磁盘块的磁盘块的序号位置映射关系""" left_x, left_y = left_top_point # 偏移量x和y short_side = length_side // 10 # 每行和每列的间隔距离 for i in range(10): for n in range(10): x, y = short_side * i + left_x, short_side * n + left_y self.canvas.create_image(x, y, anchor=tk.NW, image=self.photo_fk1) self.blocks_position_mapping[n, i] = [x, y] # 保存每个磁盘块的序号位置映射关系 for num in range(10): i = num x1, x2 = short_side * i + left_x + (short_side // 2), left_x - 20 y = short_side * i + left_y + (short_side // 2) self.canvas.create_text(x1, left_y - 20, text=f"{num}", font=("Arial", 12), anchor="center", fill="white") self.canvas.create_text(x2, y, text=f"{num}", font=("Arial", 12), anchor="center", fill="white") return self.blocks_position_mapping def modify_image_color(self, image, channel_offset): # 调整方块颜色 image_array = np.array(image) # 将图像转换为NumPy数组 modified_image_array = image_array + np.array(channel_offset) # 对每个通道进行加减操作(包括Alpha通道) modified_image_array = np.clip(modified_image_array, 0, 255) # 限制像素值在0到255之间 modified_image = Image.fromarray(np.uint8(modified_image_array)) # 创建新的图像 return modified_image def image_transition(self, file_path, side=43, channel_offset=(0, 0, 0, 0)): """修改图片大小和颜色""" image = Image.open(file_path) if sum(channel_offset) != 0: image = self.modify_image_color(image, channel_offset) # 按RGBA调整颜色 image.thumbnail((side, side)) return ImageTk.PhotoImage(image) def query_file(self): '''查询功能''' # self.sys_info("临时消息") file_name = self.file_name_label.get() if file_name in file_name_set: for item in self.FolderItems: if file_name == item[0]: file_label = initialize_fileblock(item[2], item[3]) self.canvas.delete("fk3") self.creat_file_blocks(file_label) self.blocks_num_label.delete(0, tk.END) block_nums = read_sim_fat(int(item[1]), self.SimFAT) # 通过首块fat获取全部文件fat self.load_files_list(block_nums) self.sys_info(f"查询成功!") else: print("文件夹中无该文件!") self.sys_info("文件夹中无该文件!") def check_condition(self, file_name, start_block_num, block_num): # 检查创建和保存条件 for row in self.SimFAT: # 更新唯一SimFAT表 self.fat_unique_set.update(row) if 'FF' in self.fat_unique_set: # 判断磁盘空间时,排除掉非位置字符 self.fat_unique_set.remove('FF') self.fat_unique_set.remove(100) # 收藏判断需要删除100这个非位置值 if self.clear_tag: if file_name != "" and block_num != "": # 文件名和块数不为空才能保存 if block_num.isdigit(): # 填入块数为正整数才能保存 if file_name not in file_name_set: # 文件名不重复才能保存 if len(self.fat_unique_set) + int(block_num) <= 100: if start_block_num: if int(start_block_num) not in self.fat_unique_set: # fat_arr = self.generate_fat_array(start_block_num, int(block_num), self.SimFAT) # 生成fat表 # if fat_arr: # 有返回才进行显示 return True else: self.sys_info("首块位置已被占用!") else: self.sys_info("磁盘已满!") else: self.sys_info("磁盘空间不足!") else: self.sys_info("文件名不能重复!") else: self.sys_info("请输入正整数!") else: self.sys_info("文件名或块数不能为空!") else: if self.fat_modi_tag: self.sys_info("正在执行FAT表修改任务!\n请完成FAT校验后再进行操作!") elif self.block_modi_tag: self.sys_info("正在执行磁盘块修改任务!\n请完成磁盘块校验后再进行操作!") def creat_file(self, file_name=None, f_block=None, block_num=None): print("创建文件") if not file_name: file_name = self.file_name_label.get() if not block_num: block_num = self.blocks_num_label.get() if not f_block: f_block = self.select_fat_unique() self.check = self.check_condition(file_name, f_block, block_num) # 执行数据合规检查 if self.check: # 合规时执行 if self.creating: # 初始时获取字母, self.code = get_unique_tag() self.creating = False # 获取后除非触发保存,下次创建不更新字母 file_label = initialize_fileblock(block_num, self.code) self.canvas.delete("fk3") # 新创建文件前执行一次删除 self.creat_file_blocks(file_label) self.sys_info("创建文件成功!") def creat_file_start_end_label(self, i, n, left_x, left_y, side, tags): # 创建起始和尾部标签组件 if i == 0: self.canvas.create_text(left_x, left_y - 50, anchor=tk.NW, text="起始", font=("Arial", 14), fill="white", tags=tags) offset = 15 # 箭头外扩端点偏移量 end_x = left_x + side - n * side * 0.3 # x轴线段从右到左节结束点x值 self.canvas.create_line(left_x + side, left_y - offset, end_x, left_y - offset, fill="white", tags=tags) arrow_angle = 30 # 箭头的夹角 angle_rad = arrow_angle * (pi / 180) # 计算幅度 self.canvas.create_line(end_x, left_y - offset, end_x + 10 * cos(angle_rad), left_y - offset + 10 * sin(angle_rad), fill="white", tags=tags) self.canvas.create_line(end_x, left_y - offset, end_x + 10 * cos(-angle_rad), left_y - offset + 10 * sin(-angle_rad), fill="white", tags=tags) if i == n - 1: self.canvas.create_text(left_x - i * side, left_y - 30, anchor=tk.NW, text="尾部", font=("Arial", 14), fill="white", tags=tags) def draw_blocks(self, x, y, tags, label_block, label_ctrl=None, image=None): # 画创建文件中的方块和文字 if not image: image = self.photo_fk3 self.canvas.create_image(x, y, anchor=tk.NW, image=image, tags=tags) if label_ctrl: tags = label_ctrl self.canvas.create_text(x + 5, y + 12, anchor=tk.NW, text=label_block, font=("Arial", 12), tags=tags) def creat_file_blocks(self, list: list): left_x = 465 left_y = 150 side = 43 # 元素边 tags = "fk3" n = len(list) if n <= 11: for i in range(n): x = left_x - i * side y = left_y self.draw_blocks(x, y, tags, f"{list[i]}") self.creat_file_start_end_label(i, n, left_x, left_y, side, tags) else: end_i = n - 5 # 取最后5块 for i in range(n): x = left_x - i * side y = left_y self.creat_file_start_end_label(i, 11, left_x, left_y, side, tags) if i < 5: self.draw_blocks(x, y, tags, f"{list[i]}") elif i == 5: self.draw_blocks(x, y, tags, "...") elif i < 11: self.draw_blocks(x, y, tags, f"{list[end_i]}") end_i += 1 def creat_path(self): print("创建目录项") if self.clear_tag: path_name = self.path_name_label.get() # 获取文件夹 text_ls = path_name.split(",") if text_ls[0] not in file_name_set: if len(text_ls) == 3 and text_ls[1].isdigit() and text_ls[2].isdigit(): # 确保格式和类型一致 if self.check_condition(text_ls[0], text_ls[1], text_ls[2]): self.save_file(text_ls[0], text_ls[1], text_ls[2]) self.sys_info("创建目录成功!") else: self.sys_info("请检查输入格式{'str','int','int'}!") else: self.sys_info("文件名重复!") else: self.sys_info("目前正在执行磁盘修改任务!") def show_path_info(self, ): # 显示文件目录信息 self.canvas.delete("creat_path") # 画新图前元素清空 start_x = 580 start_y = 96 tags = "creat_path" # 删除标签 word_high = 26 # 字高 self.path_delete_image = self.image_transition("img/删除.png") self.path_edit_image = self.image_transition("img/编辑.png") for i, item in enumerate(self.FolderItems): item = [str(n) for n in item] text = "\t".join(item) # 制表符加工 if start_y + i * word_high < 250: # 超出范围限制显示 self.canvas.create_text(start_x, start_y + i * word_high, anchor=tk.NW, text=text, font=("Arial", 14), fill="white", tags=tags) self.set_canvas_button([start_x + 440, start_y + i * word_high], self.path_edit_image, lambda n=i, x=start_x, y=start_y: self.path_info_edit(n, x, y), tags, bg="#434FC5") self.set_canvas_button([start_x + 470, start_y + i * word_high], self.path_delete_image, lambda n=i: self.path_info_delete(n), tags, bg="#434FC5") else: self.sys_info("文件显示将溢出") break def delete_edit_file(self, index): # 点击编辑后就先清空当前文件的保留 first_block = self.FolderItems[index][1] # 获取选中的文件的第一块位置 file_name = self.FolderItems[index][0] fat_table = read_sim_fat(int(first_block), self.SimFAT) # 获取文件的fat表 file_name_set.remove(file_name) for fat in fat_table: row = fat // 10 column = fat % 10 self.SimFAT[row][column] = 0 self.SimDisk[row][column] = 0 self.fat_unique_set.remove(fat) def path_info_edit(self, index, x, y): print("文件修改") if self.file_modi_tag: self.special_info("正在修改文件,\n修改完成请保存。") tags = "creat_path" # 删除标签 word_high = 26 # 字高 file_name = self.FolderItems[index][0] first_block = self.FolderItems[index][1] blocks = self.FolderItems[index][2] mark_char = self.FolderItems[index][3] self.path_save_image = self.image_transition("img/保存弹窗.png") self.path_cancel_image = self.image_transition("img/取消弹窗.png") y = y + index * word_high self.file_name = self.set_canvas_entry(x, y, 6, file_name, tags) # 显示entry组件,输入字符 self.first_block = self.set_canvas_entry(x + 80, y, 6, first_block, tags) self.blocks = self.set_canvas_entry(x + 160, y, 6, blocks, tags) self.mark_char = self.set_canvas_entry(x + 240, y, 6, mark_char, tags) self.set_canvas_button([x + 330, y], self.path_save_image, tags=tags, bg="#434FC5", command=lambda: self.path_info_edit_save(index)) self.set_canvas_button([x + 380, y], self.path_cancel_image, tags=tags, bg="#434FC5", command=lambda: self.path_info_edit_cancel()) self.sys_info(f"{file_name} 文件修改中...") else: self.sys_info("未开启文件校验流程,无法修改文件") # def path_info_edit_save(self, index): # 文件项编辑的保存 # if self.file_modi_tag and not self.clear_tag: # file_name = self.file_name.get() # first_block = self.first_block.get() # block_num = self.blocks.get() # old_first_block = int(self.FolderItems[index][1]) # old_fat_table = read_sim_fat(int(old_first_block), self.SimFAT) # 获取文件的fat表 # if file_name != "" and first_block != "" and block_num != "": # if first_block.isdigit() and block_num.isdigit(): # if int(first_block) not in self.fat_unique_set or int(first_block) in old_fat_table: # # if len(self.fat_unique_set) + int(block_num) - len(old_fat_table) <= 100: # b_label = self.FolderItems[index][3] # self.delete_edit_file(index) # 执行前先删除旧的记录 # self.FolderItems[index] = [file_name, first_block, block_num, b_label] # fat_arr = self.generate_fat_array(int(first_block), int(block_num)) # 重新生成fat表 # file_name_set.add(file_name) # self.load_files_list(fat_arr, b_label) # self.show_path_info() # self.sys_info("修改成功!") # else: # self.sys_info("磁盘空间不足!") # else: # self.sys_info("首块位置已被占用!") # else: # self.sys_info("请输入正整数!") # else: # self.sys_info("修改值不能为空!") # else: # self.sys_info("目前正在执行磁盘修改任务!") def path_info_edit_save(self, index): # 文件项编辑的保存 print("文件保存") if self.file_modi_tag and not self.clear_tag: self.special_info("文件已保存,可以开始校验。") file_name = self.file_name.get() # 文件名 first_block = self.first_block.get() # 磁盘首块 if first_block.isdigit(): first_block = int(first_block) block_num = self.blocks.get() # 磁盘块数 mark_char = self.mark_char.get() # 磁盘标签 self.FolderItems[index] = [file_name, first_block, block_num, mark_char] file_name_set.add(file_name) self.show_path_info() self.sys_info("修改成功!") else: self.sys_info("未开启文件修改任务") def path_info_edit_cancel(self): self.show_path_info() self.sys_info("已取消操作!") def path_info_delete(self, index): if self.clear_tag: self.delete_edit_file(index) # 清空disk和fat file_info = self.FolderItems.pop(index) # 删除该索引指向的元素 blocks_label_set.remove(file_info[3]) self.canvas.delete("fk3") self.show_path_info() # 重新显示文件信息 self.show_all_fat() self.show_all_disk() self.sys_info(f"文件 {file_info[0]} 删除成功!") else: self.sys_info("正在进行校验操作,无法执行删除操作!") def select_fat_unique(self): while True: # 确保每次不同的字符被选中 unique_num = random.randint(0, 99) if unique_num not in self.fat_unique_set: return unique_num if len(self.fat_unique_set) >= 100: return None def generate_fat_array(self, first_block: int, block_num: int): # 生成fat表文件列表 fat_arr = [first_block] self.fat_unique_set.update(fat_arr) for i in range(block_num - 1): while True: num = random.randint(1, 99) if len(self.fat_unique_set) >= 101: num = None break if num not in self.fat_unique_set: self.fat_unique_set.add(num) break if num: fat_arr.append(num) else: break return fat_arr def save_file(self, file_name=None, f_block=None, blocks=None): print("保存文件") if file_name: file_name = file_name else: file_name = self.file_name_label.get() if blocks: blocks = blocks else: blocks = self.blocks_num_label.get() if self.creating: # 如果保存时没有创建过,先创建 self.creat_file(file_name, f_block, blocks) # 保存的同时执行创建 if self.check: if f_block: f_block = int(f_block) else: f_block = self.select_fat_unique() fat_arr = self.generate_fat_array(f_block, int(blocks)) # 生成fat表 self.FolderItems.append([file_name, f_block, blocks, self.code]) # 添加到文件夹 file_name_set.add(file_name) # 添加唯一性文件名集合 self.fat_unique_set.update(fat_arr) # 将占用的磁盘位置信息添加进唯一集合,防止重复取数 self.load_files_list(fat_arr, self.code) # 根据fat表向磁盘装载文件数据并显示 self.show_path_info() # 保存后显示文件夹 self.creating = True # 上一次保存执行完成后才能开始二次执行 self.sys_info("保存成功") def restart(self): global blocks_label_set global file_name_set self.modi_fat_save() self.modi_block_save() self.save_occupy() self.canvas.delete("creat_path") self.canvas.delete("fk3") self.canvas.delete("fat_tag") self.canvas.delete("fat_disk") self.canvas.delete("label_disk") self.canvas.delete("info") self.massages = [] # 清空消息 self.FolderItems = [] # 清空文件项 blocks_label_set = set() # 块标签集合清空 file_name_set = set() # 唯一性文件名清空 self.fat_unique_set = {0} # 重置fat唯一位置检查集合 self.SimFAT = initialize_simfat() # 重置fat表 self.SimDisk = initialize_simdisk() # 重置磁盘 self.sim_fat_copy = None # fat表深拷贝初始化 self.ex_disk_oc = True # 交替显示保存占用和添加占用标志 self.ex_disk_la = True # 修改保存标签和清除标签的标志 self.sim_disk_copy = None # 磁盘块深拷贝初始化 self.block_modi_tag = False # 磁盘块修改标志置否 self.block_modi_lb = None # 磁盘块标签值初始化 self.old_key = None # FAT表上一次的记录值 self.fat_modi_num = None # 打开下一个FAT单元格之前的修改数值 self.fat_modi_tag = False # 修改状态标签,为True时进入修改状态 self.clear_tag = True # 清除标签,让标签清理和fat清理操作互斥 self.check = None # 检查磁盘条件 self.code = None # 当前磁盘块标签字母 self.creating = True # 正在创建的状态 self.file_modi_tag = False # 文件修改状态 self.sim_file_copy = None # 仿真文件复制临时列表,用于校验 self.file_save_button.config(state="normal") # 禁用一部分按键 self.fat_check_button.config(state="normal") self.disk_check_button.config(state="normal") self.creat_path_button.config(state="normal") self.add_occupy_button.config(state="normal") self.clear_file_button.config(state="normal") self.file_check_button.config(state="normal") try: self.last_step.destroy() self.next_step.destroy() except: pass self.sys_info("重置成功!") self.special_info("重置成功!") def file_check(self): global file_name_set if self.file_modi_tag: sum = 0 for i in range(len(self.FolderItems)): if self.FolderItems[i][1:] == self.sim_file_copy[i][1:]: sum+=1 file_name_set.add(self.FolderItems[i][0]) # 将新文件名添加到唯一结构 if sum == len(self.FolderItems): self.sys_info("校验正确") self.special_info("恭喜!\n文件校验成功!") self.sim_file_copy = None # 校验正确才值无 else: self.sys_info("校验错误。") self.special_info("文件校验失败。") self.file_modi_tag = False self.clear_tag = True else: self.sys_info("没有开启文件校验流程,无法校验。") def clear_file_label(self): """清除FAT表""" global file_name_set print("清除文件标签") if len(self.FolderItems)>0: if self.clear_tag: self.special_info("正在进行文件校验!\n请点击目录项的铅笔图标。\n修改目录项。") self.file_modi_tag = True self.canvas.delete("creat_path") self.clear_tag = False # 锁定文件校验状态 if not self.sim_file_copy: self.sim_file_copy = copy.deepcopy(self.FolderItems) # 深拷贝复制一份原正确列表并保存为复制对象 file_name_set = set() t0 = list() for i in range(len(self.FolderItems)): item = ["-","-","-","-"] t0.append(item) self.FolderItems = t0 self.show_path_info() self.sys_info("文件清除成功!") else: self.sys_info("正在执行校验任务,无法清除目录项!") else: self.sys_info("文件夹无文件无法清除目录!") def manual_save(self): print("手动保存") self.restart() if self.current_step: self.last_step.destroy() self.next_step.destroy() self.last_step = tk.Button(self.canvas_child, text="上一步", command=self.last_step_func) self.canvas_child.create_window([80, 180], anchor="nw", window=self.last_step) self.last_step.config(state="disabled") self.next_step = tk.Button(self.canvas_child, text="下一步", command=self.next_step_func) self.canvas_child.create_window([160, 180], anchor="nw", window=self.next_step) self.current_step = 1 self.file_info_edit() # 开启构造文件夹操作 self.file_save_button.config(state="disabled") # 禁用一部分按键 self.fat_check_button.config(state="disabled") self.disk_check_button.config(state="disabled") self.creat_path_button.config(state="disabled") self.add_occupy_button.config(state="disabled") self.clear_file_button.config(state="disabled") self.file_check_button.config(state="disabled") def last_step_func(self): print("上一步") if self.current_step == 2: print(1) self.current_step = 1 # 开启文件夹修改 self.last_step.config(state="disabled") self.file_info_edit() # 开启文件夹构造操作 self.modi_fat_save() elif self.current_step == 3: print(2) self.current_step = 2 # 开启FAT修改 self.modi_block_save() self.clear_fat_label() self.next_step.config(state="normal") self.next_step.config(text="下一步") elif self.current_step == 4: self.current_step =3 print(3) # 开启磁盘修改 self.clear_disk_label() self.next_step.config(text="完 成") def next_step_func(self): print("下一步") if self.current_step == 1: print("2") self.current_step = 2 self.last_step.config(state="normal") # 开启FAT修改 self.file_info_save() # 保存文件夹构造,并将文件信息添加到类属性self.FolderItems self.clear_fat_label() # 清除FAT表 # self.modi_fat() elif self.current_step == 2: print("3") self.current_step = 3 self.modi_fat_save() self.clear_disk_label() # 开启磁盘修改 # self.next_step.config(state="disabled") self.next_step.config(text="完 成") elif self.current_step == 3: print("4") self.current_step = 4 self.modi_block_save() # 完成 # self.next_step.config(text="完 成") self.next_step.config(text="校 验") elif self.current_step == 4: # 校验 # self.next_step.config(text="校 验") self.save_check() def save_check(self): folder_item = self.FolderItems fat_table = self.SimFAT block_table = self.SimDisk f_num = 0 for folders in folder_item: num = 0 name = folders[0] first = folders[1] if first.isdigit(): blocks = int(folders[2]) label = folders[3] fat = read_sim_fat(first, fat_table) if len(fat) == int(blocks): num += 1 for i, loca in enumerate(fat): row = loca // 10 col = loca % 10 if block_table[row][col] == f"{label}{i+1}": num += 1 if i < len(fat)-1: if fat_table[row][col] == fat[i+1]: num += 1 elif i == len(fat)-1: if fat_table[row][col] == "FF": num += 1 if num == 2*len(fat)+1: self.sys_info(f"{name}校验正确!") else: self.sys_info(f"{name}校验错误!") f_num += 1 else: self.sys_info(f"{name}校验错误!") if f_num == len(self.FolderItems): self.special_info("校验成功") try: self.last_step.destroy() self.next_step.destroy() except: pass else: self.special_info("校验失败") def file_info_edit(self): print("手动保存文件夹文件") if self.current_step ==1: self.special_info("手动保存模式。\n请先在初始区创建文件\n然后再完善文件信息。\n最后点击下一步。") tags = "creat_path" # 删除标签 self.canvas.delete(tags) x = 580 y = 96 self.file_name = self.set_canvas_entry(x, y, 6, "", tags) # 显示entry组件,输入字符 self.first_block = self.set_canvas_entry(x + 80, y, 6, "", tags) self.blocks = self.set_canvas_entry(x + 160, y, 6, "", tags) self.mark_char = self.set_canvas_entry(x + 240, y, 6, " ", tags) def file_info_save(self): self.special_info("文件保存成功\n现在开始添加文件分配表。") if self.FolderItems != []: self.FolderItems.pop() file_name = self.file_name.get() # 文件名 first_block = self.first_block.get() # 磁盘首块 if first_block.isdigit(): first_block = int(first_block) block_num = self.blocks.get() # 磁盘块数 mark_char = self.mark_char.get() # 磁盘标签 self.FolderItems.append([file_name, first_block, block_num, mark_char]) file_name_set.add(file_name) # 添加唯一文件名 blocks_label_set.add(mark_char) # 添加磁盘唯一块标志 tags = "creat_path" # 删除标签 self.canvas.delete(tags) for i, item in enumerate(self.FolderItems): item = [str(n) for n in item] text = "\t".join(item) # 制表符加工 self.canvas.create_text(580, 96, anchor=tk.NW, text=text, font=("Arial", 14), fill="white", tags=tags) self.sys_info("修改成功!") def clear_fat_label(self): print("清除表单项") self.special_info("正在进行FAT校验!\n请点击修改表单项。\n修改FAT表。") self.fat_modi_tag = True # 开启FAT修改标签 if self.clear_tag: self.canvas.delete("fat_tag") self.clear_tag = False if not self.sim_fat_copy: self.sim_fat_copy = copy.deepcopy(self.SimFAT) # 深拷贝复制一份原正确列表并保存为复制对象 self.SimFAT = initialize_simfat() # 同时清空原FAT表 self.sys_info("清除成功!") else: self.sys_info("正在执行校验任务,无法清除表单项!") def modi_fat(self): if self.fat_modi_tag: self.special_info("正在修改FAT表。\n点击FAT表对应区域修改值。\n完成后保存表单项。") if not self.sim_fat_copy and self.fat_modi_tag: self.sim_fat_copy = copy.deepcopy(self.SimFAT) # 深拷贝复制一份原正确列表并保存为复制对象 else: self.sys_info("未开启FAT校验流程。") def modi_fat_entry(self, row, column, lt_top): default = self.SimFAT[row][column] if self.fat_modi_num and self.old_key: if self.fat_modi_num.get().isdigit() or self.fat_modi_num.get().upper() == "FF": if self.fat_modi_num.get().isdigit(): self.SimFAT[self.old_key[0]][self.old_key[1]] = int(self.fat_modi_num.get()) else: self.SimFAT[self.old_key[0]][self.old_key[1]] = "FF" self.sys_info(f"{self.old_key} -> {self.fat_modi_num.get()}添加成功!") else: self.sys_info("请输入正整数,或FF!") self.canvas.delete("fat_entry") self.fat_modi_num = self.set_canvas_entry(lt_top[0] + 8, lt_top[1] + 8, 2, default, "fat_entry") self.old_key = [row, column] self.show_all_fat() def modi_fat_save(self): print("保存表单项") if self.fat_modi_tag: self.canvas.delete("fat_entry") self.fat_modi_tag = False # 修改标志置否保存后就不再能修改 self.clear_tag = True # 保存后清除项就置真 if self.fat_modi_num and self.old_key: if self.fat_modi_num.get().isdigit() or self.fat_modi_num.get().upper() == "FF": if self.fat_modi_num.get().isdigit(): self.SimFAT[self.old_key[0]][self.old_key[1]] = int(self.fat_modi_num.get()) else: self.SimFAT[self.old_key[0]][self.old_key[1]] = "FF" else: self.sys_info("请输入正整数,或FF!") self.show_all_fat() self.old_key = None for i in range(10): for n in range(10): if self.SimFAT[i][n] != 0: num = i * 10 + n self.fat_unique_set.add(num) self.sys_info("保存表单成功!") self.special_info("FAT 保存成功!\n可以开始校验。") self.fat_modi_tag = False # 修改标志置否保存后就不再能修改 else: self.sys_info("未开启FAT校验流程。") def fat_checkout(self): print("FAT校验") if self.sim_fat_copy and not self.fat_modi_tag: num = 0 tag = False for i in range(10): for n in range(10): num += 1 if self.SimFAT[i][n] != self.sim_fat_copy[i][n]: self.sys_info(f"校验失败\n{i}行{n}列错误") tag = True break if tag: break if num == 100: self.sys_info("校验正确") self.special_info("恭喜!\nFAT校验正确!") self.sim_fat_copy = None else: self.sys_info("未完成修改操作,不可校验") def clear_disk_label(self): print("清除标签") if self.clear_tag: self.block_modi_tag = True self.special_info("正在进行磁盘块校验。\n请点击修改标签,\n补充清除的磁盘块标签。") self.canvas.delete("block_entry") self.canvas.delete("label_disk") # self.canvas.delete("") self.clear_tag = False # 将清除标志置否,防止其他模块改动 if not self.sim_disk_copy: self.sim_disk_copy = copy.deepcopy(self.SimDisk) # 复制一份原正确列表并保存为复制对象 for i in range(10): for j in range(10): if self.SimDisk[i][j] != 0: self.SimDisk[i][j] = 0 self.sys_info("清除成功!") self.show_all_disk() else: self.sys_info("正在执行校验任务,无法清除磁盘模块标签。") def modi_block_lb(self): # 修改标签 print("修改标签") if self.block_modi_tag: self.special_info("正在修改磁盘块。\n点击磁盘模块区域修改值。\n完成后保存标签。") self.clear_tag = False # 修改磁盘标签时冻结文件分配表的按钮 if not self.sim_disk_copy: self.sim_disk_copy = copy.deepcopy(self.SimDisk) # 深度拷贝数组 self.ex_disk_la = False self.canvas.delete("prl") self.exchange_button_disk_label() else: self.sys_info("未开启磁盘块校验流程。") def modi_block_entry(self, row, column, lt_top): default = self.SimDisk[row][column] if self.block_modi_lb: label = self.block_modi_lb.get().upper() if label != "0": if re.match(r'^[A-Za-z]\d+$', label): # 正则表达式将匹配如 "A1"、"b2"、"Z9" 等形式的字符串 self.SimDisk[self.old_key[0]][self.old_key[1]] = label self.sys_info(f"{self.old_key} -> {label}添加成功!") else: self.sys_info("请输入正确格式,如:A1!") self.canvas.delete("block_entry") self.block_modi_lb = self.set_canvas_entry(lt_top[0] + 2, lt_top[1] + 10, 3, default, "block_entry", 12) self.block_modi_lb.select_range(0, tk.END) # 使Entry组件获得焦点(选中),以便可以直接修改值 self.old_key = [row, column] self.show_all_disk() def modi_block_save(self): print("保存标签") if self.block_modi_tag: self.canvas.delete("block_entry") self.ex_disk_la = True self.canvas.delete("psl") self.exchange_button_disk_label() if self.block_modi_lb: label = self.block_modi_lb.get().upper() if label != "0": if re.match(r'^[A-Za-z]\d+$', label): # 正则表达式将匹配如 "A1"、"b2"、"Z9" 等形式的字符串 self.SimDisk[self.old_key[0]][self.old_key[1]] = label self.sys_info(f"{self.old_key} -> {label}添加成功!") else: self.sys_info("请输入正确格式,如:A1!") for i in range(10): for n in range(10): if self.SimDisk[i][n] != 0 and self.SimDisk[i][n] != "": num = i * 10 + n code = self.SimDisk[i][n][0] # 取第一个字母 blocks_label_set.add(code) # 添加字母到字母唯一集合 self.fat_unique_set.add(num) # 将被占用的位置添加到唯一FAT表中防止被选中 self.block_modi_lb = False # 修改标签置否。 self.show_all_disk() self.block_modi_tag = False # 磁盘修改标签置否 self.clear_tag = True self.special_info("磁盘块已保存。\n可以开始校验。") self.sys_info("磁盘块保存成功!") else: self.sys_info("未开启磁盘校验流程") def add_occupy(self): print("添加占用") self.ex_disk_oc = False self.canvas.delete("pao") self.exchange_button_disk_occupy() self.sys_info("正在添加占用...") self.special_info("正在添加占用。") def add_occupy_click(self, x, y): if not self.ex_disk_oc: for key, block_lt in self.blocks_position_mapping.items(): if block_lt[0] < x < block_lt[0] + 43 and block_lt[1] < y < block_lt[1] + 43: self.SimDisk[key[0]][key[1]] = "" self.SimFAT[key[0]][key[1]] = "X" print(key[0], key[1]) self.show_all_disk() self.show_all_fat() self.sys_info(f"{key}添加成功") def disk_checkout(self): print("Disk校验") if self.sim_disk_copy and not self.block_modi_tag: num = 0 tag = False for i in range(10): for n in range(10): num += 1 if self.SimDisk[i][n] != self.sim_disk_copy[i][n]: if self.SimDisk[i][n] != "": self.sys_info(f"校验失败\n{i}行{n}列错误") tag = True break if tag: break if num == 100: self.special_info("恭喜!\n磁盘校验正确!") self.sys_info("校验正确") self.sim_disk_copy = None else: self.sys_info("未进行修改操作,不可校验") def save_occupy(self): print("保存占用") self.ex_disk_oc = True self.canvas.delete("pso") self.exchange_button_disk_occupy() for i in range(10): for n in range(10): if self.SimDisk[i][n] != 0: num = i * 10 + n self.fat_unique_set.add(num) self.sys_info("保存占用成功!") self.special_info("保存占用成功!") def on_left_click(self, event, ): x = event.x y = event.y print(x, y) if self.fat_modi_tag: for key, fat_lt in self.fat_table_position_mapping.items(): if fat_lt[0] < x < fat_lt[0] + 43 and fat_lt[1] < y < fat_lt[1] + 43: self.modi_fat_entry(key[0], key[1], fat_lt) if self.block_modi_tag: for key, block_lt in self.blocks_position_mapping.items(): if block_lt[0] < x < block_lt[0] + 43 and block_lt[1] < y < block_lt[1] + 43: self.modi_block_entry(key[0], key[1], block_lt) self.add_occupy_click(x, y) # pprint(self.SimFAT) def show_real_disk(self, title, sector): child_window = tk.Toplevel(self.root) child_window.title(title) child_window1 = tk.Toplevel(self.root) child_window1.title(f"{title}_字节解析") sector_num, Bytes = sector canvas = tk.Canvas(child_window, width=750, height=830, bg="white", ) canvas1 = tk.Canvas(child_window1, width=750, height=830, bg="white", ) BYTES_PER_LINE = 16 # 每行字节数 n = 0 s = 0 for byte in range(16): if s % 9 == 0: s = s + 1 canvas.create_text(100 + s * 35, 20 + n * 24, text=f"{byte:02X}", anchor="nw", fill="red", font=("Arial", 14)) canvas1.create_text(100 + s * 35, 20 + n * 24, text=f"{byte:02X}", anchor="nw", fill="red", font=("Arial", 14)) s += 1 n += 1 for i in range(0, len(Bytes), BYTES_PER_LINE): line_data = Bytes[i:i + BYTES_PER_LINE] print(f"{sector_num * 32 + i:08X}:", end=" ") canvas.create_text(20, 20 + n * 24, text=f"{sector_num * 32 + i:08X}:", anchor="nw", fill="red",font=("Arial", 14)) canvas1.create_text(20, 20 + n * 24, text=f"{sector_num * 32 + i:08X}:", anchor="nw", fill="red",font=("Arial", 14)) s = 0 for byte in line_data: print(f"{byte:02X}", end=" ") print(chr(byte), end=" ") if s % 9 == 0: s = s + 1 canvas.create_text(100 + s * 35, 20 + n * 24, text=f"{byte:02X}", anchor="nw", fill="black",font=("Arial", 14)) canvas1.create_text(100 + s * 35, 20 + n * 24, text=f"{chr(byte)}", anchor="nw", fill="black",font=("Arial", 14)) s += 1 print() n += 1 canvas.pack(fill=tk.BOTH, expand=True) canvas1.pack(fill=tk.BOTH, expand=True) self.sys_info(f"正在查看{title}") if __name__ == '__main__': root = tk.Tk() root.resizable(False, False) # 禁止用户调整窗口大小 main = InterfaceFile(root) # root.after(60000, close_window) root.mainloop()