You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1323 lines
62 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# -*- 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 read_bin
import numpy as np
import tkinter as tk
from files_sys_sim import *
from math import sin, cos, pi
from PIL import Image, ImageTk
from tkinter import scrolledtext
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("<Button-1>", self.on_left_click)
background_image = Image.open("/home/headless/Desktop/workspace/myshixun/src/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("/home/headless/Desktop/workspace/myshixun/src/img/pink_bg.png")
foreground_photo_pink = set_canvas_size(foreground_image_pink, "up")
foreground_image_purple = Image.open("/home/headless/Desktop/workspace/myshixun/src/img/purple_bg.png")
foreground_photo_purple = set_canvas_size(foreground_image_purple, "up")
foreground_image_jb = Image.open("/home/headless/Desktop/workspace/myshixun/src/img/jade_blue_bg.png")
foreground_photo_jb = set_canvas_size(foreground_image_jb)
foreground_image_sky_blue = Image.open("/home/headless/Desktop/workspace/myshixun/src/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("/home/headless/Desktop/workspace/myshixun/src/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("/home/headless/Desktop/workspace/myshixun/src/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("/home/headless/Desktop/workspace/myshixun/src/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("/home/headless/Desktop/workspace/myshixun/src/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("/home/headless/Desktop/workspace/myshixun/src/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("/home/headless/Desktop/workspace/myshixun/src/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("/home/headless/Desktop/workspace/myshixun/src/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("/home/headless/Desktop/workspace/myshixun/src/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("/home/headless/Desktop/workspace/myshixun/src/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("/home/headless/Desktop/workspace/myshixun/src/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("/home/headless/Desktop/workspace/myshixun/src/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("/home/headless/Desktop/workspace/myshixun/src/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("/home/headless/Desktop/workspace/myshixun/src/img/保存占用.png")
self.photo_save_occupy = ImageTk.PhotoImage(image_save_occupy)
image_add_occupy = Image.open("/home/headless/Desktop/workspace/myshixun/src/img/添加占用.png")
self.photo_add_occupy = ImageTk.PhotoImage(image_add_occupy)
self.exchange_button_disk_occupy() # 动态按钮函数用于 表示交保存和添加占用
image_revamp_label = Image.open("/home/headless/Desktop/workspace/myshixun/src/img/修改标签.png")
self.photo_revamp_label = ImageTk.PhotoImage(image_revamp_label)
image_save_label = Image.open("/home/headless/Desktop/workspace/myshixun/src/img/保存标签.png")
self.photo_save_label = ImageTk.PhotoImage(image_save_label)
self.exchange_button_disk_label() # 动态标签函数用于 表示交换修改和保存标签
image_clear_label = Image.open("/home/headless/Desktop/workspace/myshixun/src/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("/home/headless/Desktop/workspace/myshixun/src/img/fk3.png") # 黄色方块,创建文件用
self.photo_fk1 = self.image_transition("/home/headless/Desktop/workspace/myshixun/src/img/fk1.png") # 透明位置方块 提供棋盘
self.photo_fk2 = self.image_transition("/home/headless/Desktop/workspace/myshixun/src/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("<Button-1>", 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显示
def load_files_list(self, fat_ls: List[int], block_label="default"):
# 假设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("/home/headless/Desktop/workspace/myshixun/src/img/删除.png")
self.path_edit_image = self.image_transition("/home/headless/Desktop/workspace/myshixun/src/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("/home/headless/Desktop/workspace/myshixun/src/img/保存弹窗.png")
self.path_cancel_image = self.image_transition("/home/headless/Desktop/workspace/myshixun/src/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:
# 校验F
# 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():
if isinstance(first, int):
blocks = int(folders[2])
label = folders[3]
label = label[-1]
fat = read_sim_fat(first, fat_table)
# print("fat值",fat)
if len(fat) == int(blocks):
num += 1
# print("块数正确")
for i, loca in enumerate(fat):
row = loca // 10
col = loca % 10
if block_table[row][col] == f"{label}{i+1}":
num += 1
# print("block 链正确")
if i < len(fat)-1:
if fat_table[row][col] == fat[i+1]:
num += 1
# print("fat 链正确")
elif i == len(fat)-1:
if fat_table[row][col] == "FF":
num += 1
# print("fat表结束正确")
if num == 2*len(fat)+1:
self.sys_info(f"{name}校验正确!")
f_num += 1
break
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()