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.

256 lines
14 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.

# 导入模块
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()