# 导入模块 import tkinter as tk from tkinter import * from tkinter import messagebox # from data_crud import * from data_crud import * from data_line import Line_Right, line_draw, Useless_line from data_dispose_CR import Show_Right_All from data_envelop import EnvelopMove # 创建父窗口函数 class Main_Gui(): def __init__(self, init_window_name): self.init_window_name = init_window_name # 创建窗口界面 def Set_init_window(self): init_window_name = self.init_window_name root_width = init_window_name.winfo_screenwidth() # 获取window屏幕宽度 self.root_width = int(root_width / 4 * 3) # 设置父窗口界面宽度 print('父窗口界面宽度:'+str(self.root_width)) # 输出父窗口界面宽度 root_height = init_window_name.winfo_screenheight() # 获取window屏幕长度 self.root_height = int(root_height / 4 * 3) # 设置父窗口界面长度 print('父窗口界面长度:'+str(self.root_height)) # 输出父窗口界面长度 init_window_name.title('数据封包和解包模拟&X1-X4') # 标题 # 将窗口固定在屏幕中央 init_window_name.geometry(str(self.root_width)+'x'+str(self.root_height)+'+'+str(int((root_width-self.root_width)/2))+'+'+str(int((root_height-self.root_height)/2))) # 窗口大小 '''创建搭载在父窗口上的菜单''' main_menu = tk.Menu(init_window_name) filemenu = Menu(main_menu, tearoff=False) # 设置子菜单 filemenu.add_command(label='启动模拟', command=self.similar_packet) #模拟函数未完成 filemenu.add_command(label='查找', command=quit) # 寻址功能函数未完成 filemenu.add_separator() # 画线 filemenu.add_command(label='退出', command=quit) # 点击关闭页面 main_menu.add_cascade(label='open', menu=filemenu) # 主界面 init_window_name.config(menu=main_menu) # 将菜单按钮挂载在画布上 '''创建和父窗口同等大小的canvas画布''' self.cv = tk.Canvas(init_window_name, bg='#f0f0f0', # bg='white', width=self.root_width-300, height=self.root_height-180) self.cv.pack(side=tk.LEFT, anchor=tk.NW) # self.cv.grid(row=0, column=0) # self.cv.pack(anchor=tk.NW) # 画出包含仿真对象图的方框图 self.cv.create_rectangle(140, 80, self.root_width - 300, self.root_height - 180, width=3, outline="#7f6000") # 这个位置可能需要修改 # 创建固定在左侧的标识符图像 self.cv.create_image(80, 150, image=img_host) # 固定在左侧的主机对象 self.cv.create_text(80, 180, text='主机对象', font=('蔚然雅黑', 14, 'bold'), fill='black') self.cv.create_image(80, 280, image=img_router) # 固定在该canvas画布上的对象 == 路由器 self.cv.create_text(80, 310, text='路由器对象', font=('蔚然雅黑', 14, 'bold'), fill='black') '''画出仿真移动对象的图''' self.Show_Canvas_Right() # 未完成 '''这个位置开始右侧详情页面''' self.right_show_all() # 正在测试 未完成 '''设置最下方显示控件''' self.under_show_all() # 未完成 '''# 设置一个编写类封包函数''' def similar_packet(self): self.right_on_text.delete('1.0', tk.END) self.right_under_text.delete('1.0', tk.END) self.under_text.delete('1.0', tk.END) # 定义一个值用来处理信封移动事件的开启 self.open_envelop = False # 建立一个子窗口完成数据 self.packet_emu = tk.Toplevel() self.packet_emu.title('启动模拟') self.packet_emu.geometry('300x140+800+200') # 建立数据模拟数据的输入框字体 label_emu_1 = tk.Label(self.packet_emu, text='数据内容:').grid(row=0, pady=5) label_emu_2 = tk.Label(self.packet_emu, text='数据大小(kb):').grid(row=1, pady=5) label_emu_3 = tk.Label(self.packet_emu, text='数据标签:').grid(row=2, pady=5) # 建立输入框 self.entry_emu_1 = tk.Entry(self.packet_emu) self.entry_emu_1.grid(row=0, column=1) self.entry_emu_2 = tk.Entry(self.packet_emu) self.entry_emu_2.grid(row=1, column=1) self.entry_emu_3 = tk.Entry(self.packet_emu) self.entry_emu_3.grid(row=2, column=1) # 创建按钮来开始模拟 button_emu_left = tk.Button(self.packet_emu, text='开启模拟', command=self.openpack_btn).grid(row=5) # 函数未完成 return None '''创建openpack_btn函数启动按钮''' def openpack_btn(self): # 在关闭窗口前获取其中的数据 entry_emu_1_data = self.entry_emu_1.get() entry_emu_2_data = self.entry_emu_2.get() entry_emu_3_data = self.entry_emu_3.get() '''外接函数来获取对象的数据''' self.select_objlable = select_ObjLable() # # 添加if判断 if entry_emu_1_data == '' or entry_emu_2_data == '' or entry_emu_3_data == '': self.packet_emu.destroy() messagebox.showinfo('Error', '数据不能为空') # elif entry_emu_4_data == '' or entry_emu_5_data == '': # self.packet_emu.destroy() # messagebox.showinfo('Error', '发送主机or接收主机不能为空') # elif entry_emu_4_data == entry_emu_5_data and entry_emu_4_data != '': # self.packet_emu.destroy() # messagebox.showinfo('Error', '发送主机和接收主机不能相同') # elif entry_emu_4_data not in self.select_objlable and entry_emu_5_data not in self.select_objlable: # self.packet_emu.destroy() # messagebox.showinfo('Error', '发送主机or接收主机不存在') else: self.packet_emu.destroy() # 关闭启动模拟窗口 # 获取的模拟数据包信息 self.AppPackTag_Data = { 'AppPackID': entry_emu_1_data, 'AppPackSize': entry_emu_2_data, 'AppPackTag': entry_emu_3_data } print(self.AppPackTag_Data) '''这里获取需要循环发送信封的次数''' self.move_number = int(self.AppPackTag_Data['AppPackSize']) / 2048 if self.move_number > 0 and self.move_number < 1: self.move_number = 1 elif self.move_number % 1 != 0: self.move_number = int(self.move_number + 1) print('需要拆分成的数据包数量:'+str(self.move_number)) # print(self.host_date) # '''首先先建立一个判断两个主机之间是否存在通信的可能''' # 建立一个数组用来存储需要循环显示的数据 # 需要在这个位置创建一个tcp类似的子窗口 # self.Mock_TCP() '''这里建立外接函数,在移动信封的同时需要设置在最下方显示进度提示,在最右边显示完成进度''' self.envelop_move() return None '''编写模拟信封传送至交换机''' def envelop_move(self): # 移动信封的函数主体 '''在移动信封的同时需要设置在最下方显示进度提示,在最右边显示完成进度''' '''建立一个暂时的变量,可以替换''' self.unpacket = 0 self.location_all = [] # 定义用来存放对象的位置 for item in self.ObjShow_1_data: # print(item) ObjX = item['ObjX'];ObjY = item['ObjY'];ObjID = item['ObjID'];ObjType = item['ObjType'] location = (ObjX, ObjY, ObjID, ObjType) self.location_all.append(location) # 实现信封移动,并在实现的同时使最下方和最右方的canvas中显示数据 self.show_envelop = EnvelopMove(cv=self.cv,img_host=img_host, img_router=img_router, img_envelop=img_envelop,img_detail=img_detail,move_data=self.location_all,unpacket=self.unpacket, move_number=self.move_number,right_on_text=self.right_on_text,Objshow_data=self.ObjShow_1_data,AppPackTag_Data=self.AppPackTag_Data, right_under_text=self.right_under_text,under_text=self.under_text) self.show_envelop.main_envelop() # self.show_envelop.show_data_move() # print(self.ObjShow_1_data) # print(self.location_all) return None # 设置画出对象详情数据的图 def Show_Canvas_Right(self): self.simhost_all_data = get_simhost_alldata() # 获取simhost表中的所有数据 # print(self.simhost_all_data) self.ObjShow_1_data = Select_ObjShow() # 采集所有ObjShow为1的数据 print(self.ObjShow_1_data) self.line_data = line_draw(self.ObjShow_1_data) # print(self.line_data) '''外接画线函数''' self.show_line = Line_Right(cv=self.cv, line_data=self.line_data) self.show_line.line_test() '''这个位置需要添加一个固定的line存在,用来连接并不需要连通线的对象.''' self.useless_line = Useless_line(cv=self.cv, Useless_line_data=self.simhost_all_data) # 显示不需要连接的线 self.useless_line.draw_line_less() '''调用函数将对象显示在方框内''' self.show_cr = Show_Right_All(cv=self.cv, all_data=self.simhost_all_data) self.show_cr.Show_img(img_host=img_host, img_router=img_router) return None # 测试 在最左侧实现详情数据 def right_show_all(self): '''更换编写方式使用最原本的text特性''' self.right_on_label = tk.Label(self.init_window_name, text='发送主机详情:',font=('蔚然雅黑', 12, 'bold')) # self.right_on_label.pack(side=tk.TOP, fill=tk.Y, padx=10, pady=10) self.right_on_label.pack(anchor=tk.NW, fill=tk.Y, padx=5, pady=5) self.right_on_text = tk.Text(self.init_window_name, width=40, height=22) self.right_on_text.pack(anchor=tk.NW, fill=tk.Y, padx=5, pady=5) self.right_under_label = tk.Label(self.init_window_name, text='接收主机详情:', font=('蔚然雅黑', 12, 'bold')) self.right_under_label.pack(anchor=tk.NW, fill=tk.Y, padx=5, pady=5) self.right_under_text = tk.Text(self.init_window_name, width=40, height=22) self.right_under_text.pack(anchor=tk.NW, fill=tk.Y, padx=5, pady=5) self.right_on_text.configure(font=("TkDefaultFont", 12)) self.right_under_text.configure(font=("TkDefaultFont", 12)) # self.canvas_right_detail = tk.Canvas(self.cv, width=290, height=700, bg='white') # self.cv.create_window(1290, 280, window=self.canvas_right_detail, width=290, height=705) # self.canvas_right_detail.create_text(80, 90, text='发送主机 '+self.ObjShow_1_data[0]['ObjLable']+' 详情:', font=('蔚然雅黑', 12, 'bold'), fill='black') # '''在该canvas画布下的子画布中创建两个frame组件''' # self.right_on_frame = tk.Frame(self.canvas_right_detail, width=280, height=270, bg='lightgray') # self.canvas_right_detail.create_window(145, 250, window=self.right_on_frame) # # 接收主机的属性 # self.canvas_right_detail.create_text(80, 400, text='接收主机 '+self.ObjShow_1_data[-1]['ObjLable']+' 详情:', font=('蔚然雅黑', 12, 'bold'), fill='black') # self.right_under_frame = tk.Frame(self.canvas_right_detail, width=280, height=270, bg='lightgray') # self.canvas_right_detail.create_window(145, 560, window=self.right_under_frame) # ''' # 接下来的目的: # 1.在下面的两个frame组件中加入文本框组件 # 2.可以实现分批次的显示数据 # ''' # self.canvas_on_ftext = tk.Text(self.right_on_frame, width=10, height=10) # self.canvas_on_ftext.pack() return None # 测试 在最下方设置操作输出框 def under_show_all(self): '''更换方式显示''' scrollbar_y = tk.Scrollbar(self.init_window_name) scrollbar_y.place(x=1130, y=638,relheight=0.21) # scrollbar_x = tk.Scrollbar(self.init_window_name, orient=tk.HORIZONTAL) # scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X) self.under_label = tk.Label(self.init_window_name, text='数据传输进度: ', font=('蔚然雅黑', 12, 'bold')) # self.under_label.pack(side=tk.BOTTOM, anchor=tk.SW) self.under_label.place(x=20, y=638) self.under_text = tk.Text(self.init_window_name, width=123, height=10) # self.under_text.place(x=140, y=638, relheight=1) self.under_text.place(x=140, y=638) self.under_text.configure(font=("TkDefaultFont", 12)) scrollbar_y.config(command=self.under_text.yview) self.under_text.config(yscrollcommand=scrollbar_y.set) # scrollbar_x.config(command=self.under_text.xview) # # 设置子canvas画布 # self.canvas_under_detail = tk.Canvas(self.cv,width=2000, height=177, bg='white') # self.cv.create_window(450, 720, window=self.canvas_under_detail, width=2000, height=177) # self.canvas_under_detail.create_text(750, 21,text='数据传输进度: ', font=('蔚然雅黑', 12, 'bold'), fill='black') # '''创建在最下方的canvas画布中的详情显示frame''' # self.canvas_under_frame = tk.Frame(self.canvas_under_detail, width=1500, height=143, bg='lightgray') # self.canvas_under_detail.create_window(1250, 105, window=self.canvas_under_frame) return None if __name__ == '__main__': init_Windows = tk.Tk() # 创建一个父窗口 img_host = PhotoImage(file='./images/主机_1.png') img_router = PhotoImage(file='./images/路由器_1.png') img_envelop = PhotoImage(file='./images/信封_1.png') img_detail = PhotoImage(file='./images/详情头_1.png') Gui = Main_Gui(init_Windows) Gui.Set_init_window() init_Windows.mainloop()