def __init__(self, *args, **kwargs): tk.Frame.__init__(self, *args, **kwargs) self.title_bar = TitleBar(self, 'Dissector Builder Area') self.frame_canvas = tk.Frame(self, bg='white') self.frame_palette = SubAreaPalette(self) self.hbar = tk.Scrollbar(self, orient=tk.HORIZONTAL) self.vbar = tk.Scrollbar(self, orient=tk.VERTICAL) canvas = CanvasDnd(self.frame_canvas, bg='white', width=800, height=500, scrollregion=(0, 0, 5000, 5000)) canvas.config(xscrollcommand=self.hbar.set, yscrollcommand=self.vbar.set) self.hbar.config(command=canvas.xview) self.vbar.config(command=canvas.yview) canvas.hbar = self.hbar canvas.vbar = self.vbar # lbl_canvas = tk.Label(self.frame_canvas, text='Canvas') # Parent set-up self.title_bar.pack(fill=tk.X, expand=True, side=tk.TOP) self.frame_palette.pack(fill=tk.BOTH, expand=True, side=tk.RIGHT) self.vbar.pack(fill=tk.Y, expand=False, side=tk.RIGHT) self.frame_canvas.pack(fill=tk.BOTH, expand=False) self.hbar.pack(fill=tk.X, expand=True) # Frame Canvas set-up canvas.pack(fill=tk.BOTH, expand=True)
def __init__(self, *args, **kwargs): tk.Frame.__init__(self, *args, **kwargs) self.title_bar = TitleBar(self, 'Project Navigator') self.title_bar.bind() self.title_bar.pack(padx=2) self.label = tk.Label(self, text=Workspace.current.name) self.label.bind() self.label.pack() self.im_close = tk.PhotoImage(file="Closef.gif").subsample(5, 5) self.im_open = tk.PhotoImage(file="Openf.gif").subsample(5, 5) self.vars = [] self.lbls = [] for p in Workspace.current.projects: var_name = tk.StringVar(self, p.name) lbl = tk.Label(self, textvariable=var_name, compound='left', pady=10, padx=10, image=self.im_close) lbl.bind("<Button-1>", lambda event: self.on_click(var_name, lbl)) lbl.pack() self.vars.append(var_name) self.lbls.append(lbl) self.lbls[Workspace.current.selected_project]['image'] = self.im_open
def __init__(self, title, *args, **kwargs): tk.Frame.__init__(self, *args, **kwargs) self.title_bar = TitleBar(self, title) self.title_bar.set_max(lambda: self.text.grid()) self.title_bar.set_min(lambda: self.text.grid_remove()) self.text = tk.Text(self, width=35, height=20) self.title_bar.grid(column=0, row=0) self.text.grid(column=0, row=1)
def __init__(self, parent=None): super().__init__(parent) self.monitor_info = None self.titleBar = TitleBar(self) self.windowEffect = WindowEffect() # 取消边框 self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowSystemMenuHint | Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint) # 添加阴影和窗口动画 self.windowEffect.addShadowEffect(self.winId()) self.windowEffect.addWindowAnimation(self.winId()) self.resize(500, 500) self.titleBar.raise_()
def __init__(self, master, INFO_ID): View.__init__(self, master, INFO_ID) self['bg'] = 'red' self['height'] = 100 self['width'] = 300 from titlebar import TitleBar self.titlebar = TitleBar(self, 'Connector') # StringVars self.var_src = tk.StringVar(self, 'None') self.var_dst = tk.StringVar(self, 'None') self.src_idx = -1 self.dst_idx = -1 # Components self.arrow = tk.Label() self.src = tk.OptionMenu(self, self.var_src, None) self.src.bind('<Button-1>', self.on_menu_open) self.dst = tk.OptionMenu(self, self.var_dst, None) self.dst.bind('<Button-1>', self.on_menu_open) # Layout self.create_window((101, 10), width=400, window=self.titlebar) self.create_window((65, 40), window=self.src) self.create_window((65, 80), window=self.dst)
def __init__(self, master, INFO_ID): View.__init__(self, master, INFO_ID) self['height']=30 self['width']=150 self.title_bar = TitleBar(self, 'End Field') self.create_window((75,12),width=150,window=self.title_bar)
def __init__(self, master, INFO_ID): View.__init__(self, master, INFO_ID) self['height'] = 150 self.titlebar = TitleBar(self, 'Start Field []') self.protocol_name_label = tk.Label(text='Protocol Name') self.var_proto_name = tk.StringVar() self.entry_proto_name = tk.Entry(self, textvariable=self.var_proto_name, width=40) self.create_window((47,50),window=self.protocol_name_label) self.create_window((190, 10), width=380, window=self.titlebar) self.create_window((250, 50), window=self.entry_proto_name) self.protocol_desc_label = tk.Label(text='Protocol Description') self.var_proto_desc = tk.StringVar() self.entry_proto_desc = tk.Entry(self, textvariable=self.var_proto_desc, width=40) self.create_window((60,70), window=self.protocol_desc_label) self.create_window((250,70), window= self.entry_proto_desc) ################ self.protocol_dpn_label = tk.Label(text='Dependent Protocol Name') self.var_dep_proto_name = tk.StringVar() self.entry_dep_proto_name = tk.Entry(self, textvariable=self.var_dep_proto_name, width=35) self.create_window((76, 90), window=self.protocol_dpn_label) self.create_window((265, 90), window=self.entry_dep_proto_name) ################# self.dp_label = tk.Label(text='Dependency Pattern') self.var_dep_pattern = tk.StringVar() self.entry_dp = tk.Entry(self, textvariable=self.var_dep_pattern, width=40) self.create_window((60, 110), window=self.dp_label) self.create_window((250, 117), window=self.entry_dp) self['height']=150
def __init__(self, master, INFO_ID): View.__init__(self, master, INFO_ID) self['height'] = 210 self.titlebar = TitleBar(self, 'Field []') self.var_name = tk.StringVar() self.var_abbreviation = tk.StringVar() self.var_description = tk.StringVar() self.var_datatype = tk.StringVar() self.var_base = tk.StringVar() self.var_vc = tk.StringVar() self.var_required = tk.StringVar() self.proto_name_label = tk.Label(text="Name") self.entry_name = tk.Entry(self, textvariable=self.var_name, width=40) self.abbr_label = tk.Label(text="Abbreviation") self.abbr_entry = tk.Entry(self, textvariable=self.var_abbreviation, width=40) self.desc_label = tk.Label(text="Description") self.desc_entry = tk.Entry(self, textvariable=self.var_description, width=40) self.datatype_list = ( 'types.NONE', 'ftypes.PROTOCOL', 'ftypes.BOOLEAN', 'ftypes.UINT8', 'ftypes.UINT16', 'ftypes.UINT24', 'ftypes.UINT32', 'ftypes.UINT64', 'ftypes.INT8', 'ftypes.INT16', 'ftypes.INT24', 'ftypes.INT32', 'ftypes.INT64', 'ftypes.FLOAT', 'ftypes.DOUBLE', 'ftypes.ABSOLUTE_TIME', 'ftypes.RELATIVE_TIME', 'ftypes.STRING', 'ftypes.STRINGZ', 'ftypes.UINT_STRING', 'ftypes.ETHER', 'ftypes.BYTES', 'ftypes.UINT_BYTES', 'ftypes.IPv4', 'ftypes.IPv6', 'ftypes.IPXNET', 'ftypes.FRAMENUM', 'ftypes.PCRE', 'ftypes.GUID', 'ftypes.OID', 'ftypes.EUI6') self.var_datatype.set(self.datatype_list[0]) self.entry_datatype = tk.OptionMenu(self, self.var_datatype, *self.datatype_list) self.datatype_label = tk.Label(text="Datatype") self.base_label = tk.Label(text="Base") self.base_list = ('base.NONE', 'base.DEC', 'base.HEX', 'base.OCT', 'base.DEC_HEX', 'base.HEX_DEC') self.var_base.set(self.base_list[0]) self.entry_base = tk.OptionMenu(self, self.var_base, *self.base_list) self.vc_label = tk.Label(text="Value Constraint") self.vc_entry = tk.Entry(self, textvariable=self.var_vc, width=40) self.required_label = tk.Label(text="Required") self.required_list = ('Yes', 'No') self.var_required.set(self.required_list[0]) self.required_entry = tk.OptionMenu(self, self.var_required, *self.required_list) self.create_window((47, 50), window=self.proto_name_label) self.create_window((190, 12), width=380, window=self.titlebar) self.create_window((250, 50), window=self.entry_name) self.create_window((38, 70), window=self.abbr_label) self.create_window((250, 70), window=self.abbr_entry) self.create_window((35, 90), window=self.desc_label) self.create_window((250, 90), window=self.desc_entry) self.create_window((250, 118), window=self.entry_datatype) self.create_window((28, 118), window=self.datatype_label) self.create_window((17, 140), window=self.base_label) self.create_window((250, 145), window=self.entry_base) self.create_window((45, 170), window=self.vc_label) self.create_window((250, 170), window=self.vc_entry) self.create_window((28, 196), window=self.required_label) self.create_window((250, 196), window=self.required_entry)
class AreaProjectNavigation(tk.Frame): def on_click(self, var_name, lbl): # Close the previous project prev_lbl = self.lbls[Workspace.current.selected_project] prev_lbl['image'] = self.im_close # Open the new project lbl['image'] = self.im_open # idx = next((i for i in range(len(Workspace.current.projects)) if Workspace.current.projects[i] == var_name.get()), 0) # Workspace.current.selected_project = idx def __init__(self, *args, **kwargs): tk.Frame.__init__(self, *args, **kwargs) self.title_bar = TitleBar(self, 'Project Navigator') self.title_bar.bind() self.title_bar.pack(padx=2) self.label = tk.Label(self, text=Workspace.current.name) self.label.bind() self.label.pack() self.im_close = tk.PhotoImage(file="Closef.gif").subsample(5, 5) self.im_open = tk.PhotoImage(file="Openf.gif").subsample(5, 5) self.vars = [] self.lbls = [] for p in Workspace.current.projects: var_name = tk.StringVar(self, p.name) lbl = tk.Label(self, textvariable=var_name, compound='left', pady=10, padx=10, image=self.im_close) lbl.bind("<Button-1>", lambda event: self.on_click(var_name, lbl)) lbl.pack() self.vars.append(var_name) self.lbls.append(lbl) self.lbls[Workspace.current.selected_project]['image'] = self.im_open
def __init__(self, *args, **kwargs): tk.Frame.__init__(self, *args, **kwargs) self.title_bar = TitleBar(self, "Packet Stream Area") self.table = tk.Frame(self) number = tk.Button(self.table, text="No.") time = tk.Button(self.table, text="Time") source = tk.Button(self.table, text="Source") destination = tk.Button(self.table, text="Destination") protocol = tk.Button(self.table, text="Protocol") info = tk.Button(self.table, text="Info") number.grid(row=0, column=0, sticky="E W") time.grid(row=0, column=1, sticky="E W") source.grid(row=0, column=2, sticky="E W") destination.grid(row=0, column=3, sticky="E W") protocol.grid(row=0, column=4, sticky="E W") info.grid(row=0, column=5, sticky="E W") self.table.grid(row=1, column=0) # self.grid(column=0, row=1) self.title_bar.set_max(lambda: self.table.grid()) self.title_bar.set_min(lambda: self.table.grid_forget()) self.title_bar.grid(column=0, row=0, sticky="E W") ########################################################## pcap_path = "C:\\Users\\xeroj\Desktop\\Local_Programming\\Python-Software-GUI\\example\\icmp.pcap" lua_path = "C:\\Users\\xeroj\Desktop\\Local_Programming\\Python-Software-GUI\\example\\icmp.lua" # self.fill_table(text) pdmltext = sp.check_output("tshark -r " + pcap_path + " -T pdml -X lua_script:" + lua_path) packets_info = self.get_packet_info("text.pdml", pdmltext) self.fill_table(packets_info)
def init_frames(self): self.title_bar = TitleBar(self, 'Palette') self.title_bar.grid(column=0, row=0, columnspan=10, sticky='NWWE') self.frame_fields = tk.Frame(self, bg='white') self.frame_constructs = tk.Frame(self, bg='white') self.frame_decision = tk.Frame(self.frame_constructs) self.frame_connector = tk.Frame(self.frame_constructs) self.frame_expression = tk.Frame(self.frame_constructs) # Field Icon self.icon_field = tk.Label(self, text='', image=self.im_folder_open) self.lbl_field = tk.Label(self, text='Field', font=('', '12')) self.lbl_field.bind('<Button-1>', self.on_btn_click_field) self.icon_field.bind('<Button-1>', self.on_btn_click_field) # Construct Icon self.icon_construct = tk.Label(self, text='', image=self.im_folder_open) self.lbl_construct = tk.Label(self, text='Construct', font=('', '12')) self.lbl_construct.bind('<Button-1>', self.on_btn_click_construct) self.icon_construct.bind('<Button-1>', self.on_btn_click_construct) # Field Icon -> Field Frame -> Construct Icon -> Construct Frame self.icon_field.grid(row=1, column=0, sticky='WE') self.lbl_field.grid(row=1, column=1, columnspan=5, sticky='WE') self.frame_fields.grid(row=2, column=1, sticky='WE') self.icon_construct.grid(row=3, column=0, sticky='WE') self.lbl_construct.grid(row=3, column=1, columnspan=5, sticky='WE') self.frame_constructs.grid(row=4, column=1, columnspan=10, sticky='WE') # Decision Frame -> Connector Frame -> Expression Frame self.frame_decision.grid(column=0, row=1, columnspan=4, sticky='E') self.frame_connector.grid(column=0, row=2, columnspan=2, sticky='E') self.frame_expression.grid(column=0, row=3, columnspan=2, sticky='E')
class FramelessWindow(QWidget): BORDER_WIDTH = 5 def __init__(self, parent=None): super().__init__(parent) self.monitor_info = None self.titleBar = TitleBar(self) self.windowEffect = WindowEffect() # 取消边框 self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowSystemMenuHint | Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint) # 添加阴影和窗口动画 self.windowEffect.addShadowEffect(self.winId()) self.windowEffect.addWindowAnimation(self.winId()) self.resize(500, 500) self.titleBar.raise_() def isWindowMaximized(self, hWnd) -> bool: """ 判断窗口是否最大化 """ # 返回指定窗口的显示状态以及被恢复的、最大化的和最小化的窗口位置,返回值为元组 windowPlacement = win32gui.GetWindowPlacement(hWnd) if not windowPlacement: return False return windowPlacement[1] == win32con.SW_MAXIMIZE def nativeEvent(self, eventType, message): """ 处理windows消息 """ msg = MSG.from_address(message.__int__()) if msg.message == win32con.WM_NCHITTEST: # 解决多屏下会出现鼠标一直为拖动状态的问题 xPos = (win32api.LOWORD(msg.lParam) - self.frameGeometry().x()) % 65536 yPos = win32api.HIWORD(msg.lParam) - self.frameGeometry().y() w, h = self.width(), self.height() lx = xPos < self.BORDER_WIDTH rx = xPos + 9 > w - self.BORDER_WIDTH ty = yPos < self.BORDER_WIDTH by = yPos > h - self.BORDER_WIDTH if lx and ty: return True, win32con.HTTOPLEFT elif rx and by: return True, win32con.HTBOTTOMRIGHT elif rx and ty: return True, win32con.HTTOPRIGHT elif lx and by: return True, win32con.HTBOTTOMLEFT elif ty: return True, win32con.HTTOP elif by: return True, win32con.HTBOTTOM elif lx: return True, win32con.HTLEFT elif rx: return True, win32con.HTRIGHT elif msg.message == win32con.WM_NCCALCSIZE: if self.isWindowMaximized(msg.hWnd): self.monitorNCCALCSIZE(msg) return True, 0 elif msg.message == win32con.WM_GETMINMAXINFO: if self.isWindowMaximized(msg.hWnd): window_rect = win32gui.GetWindowRect(msg.hWnd) if not window_rect: return False, 0 # 获取显示器句柄 monitor = win32api.MonitorFromRect(window_rect) if not monitor: return False, 0 # 获取显示器信息 monitor_info = win32api.GetMonitorInfo(monitor) monitor_rect = monitor_info['Monitor'] work_area = monitor_info['Work'] # 将lParam转换为MINMAXINFO指针 info = cast(msg.lParam, POINTER(MINMAXINFO)).contents # 调整窗口大小 info.ptMaxSize.x = work_area[2] - work_area[0] info.ptMaxSize.y = work_area[3] - work_area[1] info.ptMaxTrackSize.x = info.ptMaxSize.x info.ptMaxTrackSize.y = info.ptMaxSize.y # 修改左上角坐标 info.ptMaxPosition.x = abs(window_rect[0] - monitor_rect[0]) info.ptMaxPosition.y = abs(window_rect[1] - monitor_rect[1]) return True, 1 return QWidget.nativeEvent(self, eventType, message) def resizeEvent(self, e): """ 改变标题栏大小 """ super().resizeEvent(e) self.titleBar.resize(self.width(), 40) # 更新最大化按钮图标 self.titleBar.maxBt.setMaxState( self.isWindowMaximized(int(self.winId()))) def monitorNCCALCSIZE(self, msg: MSG): """ 调整窗口大小 """ monitor = win32api.MonitorFromWindow(msg.hWnd) # 如果没有保存显示器信息就直接返回,否则接着调整窗口大小 if monitor is None and not self.monitor_info: return elif monitor is not None: self.monitor_info = win32api.GetMonitorInfo(monitor) # 调整窗口大小 params = cast(msg.lParam, POINTER(NCCALCSIZE_PARAMS)).contents params.rgrc[0].left = self.monitor_info['Work'][0] params.rgrc[0].top = self.monitor_info['Work'][1] params.rgrc[0].right = self.monitor_info['Work'][2] params.rgrc[0].bottom = self.monitor_info['Work'][3]
class AreaPacketStream(Area): def __init__(self, *args, **kwargs): Area.__init__(self, "Packet Stream Area", *args, **kwargs) def __init__(self, *args, **kwargs): tk.Frame.__init__(self, *args, **kwargs) self.title_bar = TitleBar(self, "Packet Stream Area") self.table = tk.Frame(self) number = tk.Button(self.table, text="No.") time = tk.Button(self.table, text="Time") source = tk.Button(self.table, text="Source") destination = tk.Button(self.table, text="Destination") protocol = tk.Button(self.table, text="Protocol") info = tk.Button(self.table, text="Info") number.grid(row=0, column=0, sticky="E W") time.grid(row=0, column=1, sticky="E W") source.grid(row=0, column=2, sticky="E W") destination.grid(row=0, column=3, sticky="E W") protocol.grid(row=0, column=4, sticky="E W") info.grid(row=0, column=5, sticky="E W") self.table.grid(row=1, column=0) # self.grid(column=0, row=1) self.title_bar.set_max(lambda: self.table.grid()) self.title_bar.set_min(lambda: self.table.grid_forget()) self.title_bar.grid(column=0, row=0, sticky="E W") ########################################################## pcap_path = "C:\\Users\\xeroj\Desktop\\Local_Programming\\Python-Software-GUI\\example\\icmp.pcap" lua_path = "C:\\Users\\xeroj\Desktop\\Local_Programming\\Python-Software-GUI\\example\\icmp.lua" # self.fill_table(text) pdmltext = sp.check_output("tshark -r " + pcap_path + " -T pdml -X lua_script:" + lua_path) packets_info = self.get_packet_info("text.pdml", pdmltext) self.fill_table(packets_info) def get_packet_info(self, name, pdmltext): file = open(name, 'w') file.write(pdmltext) file.close() tree = ET.parse(name) root = tree.getroot() number = 0 packets = [] for packet in root: packet_info = PacketStreamItem() for proto in packet: if proto.attrib['name'] == 'ip': for field in proto: if field.attrib['name'] == 'ip.proto': packet_info.protocol = field.attrib[ 'showname'].split(' ')[1] if proto.attrib['name'] == 'frame': for field in proto: if field.attrib['name'] == 'frame.time_delta': packet_info.time = field.attrib['show'] if proto.attrib['name'] == 'ip': attr = proto.attrib["showname"].split(',') packet_info.source = attr[1].split(' ')[2] packet_info.destination = attr[2].split(' ')[2] packet_info.number = number number += 1 packets.append(packet_info) return packets def fill_table(self, packets_info): count = 1 for info in packets_info: number_label = tk.Label(self.table, text=info.number) time_label = tk.Label(self.table, text=info.time) source_label = tk.Label(self.table, text=info.source) dest_label = tk.Label(self.table, text=info.destination) protocol_label = tk.Label(self.table, text=info.protocol) number_label.grid(row=count, column=0) time_label.grid(row=count, column=1) source_label.grid(row=count, column=2) dest_label.grid(row=count, column=3) protocol_label.grid(row=count, column=4) count += 1
class SubAreaPalette(tk.Frame): def __init__(self, parent): tk.Frame.__init__(self, parent) self.is_field_open = True self.is_construct_open = True self.init_images() self.init_frames() self.init_fields() self.init_constructs() def init_images(self): self.im_folder_closed = ImageTk.PhotoImage( Image.open('folder_closed.png').resize((16, 16), Image.ANTIALIAS)) self.im_folder_open = ImageTk.PhotoImage(Image.open('folder_opened.png').resize((16, 16), Image.ANTIALIAS)) self.im_circle = ImageTk.PhotoImage( Image.open('circular-shape-silhouette.png').resize((40, 40), Image.ANTIALIAS)) self.im_arrow = ImageTk.PhotoImage(Image.open('arrow-pointing-to-right.png')) self.im_diamond = ImageTk.PhotoImage(Image.open('rhombus.png').resize((40, 40), Image.ANTIALIAS)) def init_frames(self): self.title_bar = TitleBar(self, 'Palette') self.title_bar.grid(column=0, row=0, columnspan=10, sticky='NWWE') self.frame_fields = tk.Frame(self, bg='white') self.frame_constructs = tk.Frame(self, bg='white') self.frame_decision = tk.Frame(self.frame_constructs) self.frame_connector = tk.Frame(self.frame_constructs) self.frame_expression = tk.Frame(self.frame_constructs) # Field Icon self.icon_field = tk.Label(self, text='', image=self.im_folder_open) self.lbl_field = tk.Label(self, text='Field', font=('', '12')) self.lbl_field.bind('<Button-1>', self.on_btn_click_field) self.icon_field.bind('<Button-1>', self.on_btn_click_field) # Construct Icon self.icon_construct = tk.Label(self, text='', image=self.im_folder_open) self.lbl_construct = tk.Label(self, text='Construct', font=('', '12')) self.lbl_construct.bind('<Button-1>', self.on_btn_click_construct) self.icon_construct.bind('<Button-1>', self.on_btn_click_construct) # Field Icon -> Field Frame -> Construct Icon -> Construct Frame self.icon_field.grid(row=1, column=0, sticky='WE') self.lbl_field.grid(row=1, column=1, columnspan=5, sticky='WE') self.frame_fields.grid(row=2, column=1, sticky='WE') self.icon_construct.grid(row=3, column=0, sticky='WE') self.lbl_construct.grid(row=3, column=1, columnspan=5, sticky='WE') self.frame_constructs.grid(row=4, column=1, columnspan=10, sticky='WE') # Decision Frame -> Connector Frame -> Expression Frame self.frame_decision.grid(column=0, row=1, columnspan=4, sticky='E') self.frame_connector.grid(column=0, row=2, columnspan=2, sticky='E') self.frame_expression.grid(column=0, row=3, columnspan=2, sticky='E') def init_fields(self): self.circlepic = tk.PhotoImage(file="circle.gif") self.sized_circle = self.circlepic.subsample(10, 10) self.circlebpic = tk.PhotoImage(file="circleb.gif") self.sized_circleb = self.circlebpic.subsample(10, 10) self.start_field = tk.Button(self.frame_fields,text='Start Field',image=self.sized_circle, compound='center') self.start_field.bind('<ButtonPress>',lambda event: self.on_dnd_start(event, PaletteType.START_FIELD)) self.start_field.grid(column=0,row=1) self.field_1 = tk.Button(self.frame_fields, text='Field (1 byte)') self.field_1.bind('<ButtonPress>', lambda event: self.on_dnd_start(event, PaletteType.FIELD)) self.field_1.grid(column=1, row=1) self.field_2 = tk.Button(self.frame_fields, text='Field (2 byte') self.field_2.bind('<ButtonPress>', lambda event: self.on_dnd_start(event, PaletteType.FIELD)) self.field_2.grid(column=0, row=2) self.field_4 = tk.Button(self.frame_fields, text='Field (4 byte') self.field_4.bind('<ButtonPress>', lambda event: self.on_dnd_start(event, PaletteType.FIELD)) self.field_4.grid(column=1, row=2) self.field_8 = tk.Button(self.frame_fields, text='Field (8 byte') self.field_8.bind('<ButtonPress>', lambda event: self.on_dnd_start(event, PaletteType.FIELD)) self.field_8.grid(column=0, row=3) self.field_16 = tk.Button(self.frame_fields, text='Field (16 byte') self.field_16.bind('<ButtonPress>', lambda event: self.on_dnd_start(event, PaletteType.FIELD)) self.field_16.grid(column=0, row=3) self.end_field = tk.Button(self.frame_fields, text='End Field', image=self.sized_circleb, compound='center', fg='red') self.end_field.bind('<ButtonPress>', lambda event: self.on_dnd_start(event, PaletteType.END_FIELD)) self.end_field.grid(column=1, row=3) def init_constructs(self): self.init_decision_constructs() self.init_connector_constructs() self.init_expression_constructs() def init_decision_constructs(self): lbl_decision = tk.Label(self.frame_decision, text='Decision') lbl_decision.grid(column=0, row=0, sticky='W') btn_expression = tk.Button(self.frame_decision, text='Expression', image=self.im_diamond, compound=tk.CENTER) btn_expression.grid(column=0, row=1) def init_connector_constructs(self): lbl = tk.Label(self.frame_connector, text='Connector') lbl.grid(column=0, row=0, sticky='WE') connector = tk.Button(self.frame_connector, text='', image=self.im_arrow, compound=tk.CENTER, bg='white') connector.bind("<Button-1>", lambda event: self.on_dnd_start(event, PaletteType.CONNECTOR)) connector.grid(column=0, row=1, sticky='WE') def init_expression_constructs(self): lbl = tk.Label(self.frame_expression, text='Expression') lbl2 = tk.Label(self.frame_expression, text='Relational Operator', bg='gray') op_frame1 = tk.Frame(self.frame_expression) op_less_than = tk.Button(op_frame1, text='<') op_less_than_equal = tk.Button(op_frame1, text='<=') op_greater_than = tk.Button(op_frame1, text='>') op_greater_than = tk.Button(op_frame1, text='>=') op_equal = tk.Button(op_frame1, text='==') op_not_equal = tk.Button(op_frame1, text='~=') lbl3 = tk.Label(self.frame_expression, text='Logical Operator') op_frame2 = tk.Frame(self.frame_expression) op_and = tk.Button(op_frame2, text='And') op_or = tk.Button(op_frame2, text='Or') op_not = tk.Button(op_frame2, text='Not') operand = tk.Button(self.frame_expression, text='Operand') lbl.grid(column=0, row=0, sticky='WE') lbl2.grid(column=0, row=1, sticky='WE') op_frame1.grid(column=0, row=2, sticky='WE') lbl3.grid(column=0, row=3, sticky='WE') op_frame2.grid(column=0, row=4) op_less_than.grid(column=1, row=0, sticky='WE') op_less_than_equal.grid(column=2, row=0, sticky='WE') op_greater_than.grid(column=3, row=0, sticky='WE') op_greater_than.grid(column=4, row=0, sticky='WE') op_equal.grid(column=5, row=0, sticky='WE') op_not_equal.grid(column=6, row=0, sticky='WE') op_and.grid(column=1, row=0, sticky='WE') op_or.grid(column=2, row=0, sticky='WE') op_not.grid(column=3, row=0, sticky='WE') operand.grid(column=0, row=7, sticky='WE') def on_btn_click_construct(self, event): if self.is_construct_open: self.icon_construct.configure(image=self.im_folder_closed) self.frame_constructs.grid_remove() else: self.icon_construct.configure(image=self.im_folder_open) self.frame_constructs.grid() self.is_construct_open = not self.is_construct_open def on_btn_click_field(self, event): if self.is_field_open: self.icon_field.configure(image=self.im_folder_closed) self.frame_fields.grid_remove() else: self.icon_field.configure(image=self.im_folder_open) self.frame_fields.grid() self.is_field_open = not self.is_field_open def on_dnd_start(self, event, type): # Create placeholder info and add it to tree print("dnd entered") ID = len(Workspace.current.get_tree().fields) info = self.info_from_type(ID, type) Workspace.current.get_tree().fields.insert(ID, info) ThingToDrag = Draggable(self, ID) Tkdnd.dnd_start(ThingToDrag, event) def info_from_type(self, ID, type): if type == PaletteType.START_FIELD: return StartFieldInfo() elif type == PaletteType.FIELD: return FieldInfo() elif type == PaletteType.END_FIELD: return EndFieldInfo() elif type == PaletteType.CONNECTOR: return ConnectorInfo() return StartFieldInfo()