def PausePopup(self, newColor="black", trim=False): tl = Toplevel(root) tl.attributes('-topmost', 'true') tl.grab_set() tl.title("Tool change") msg = "change the tool for a next color" if trim: tl.title("Thread trim") msg = "cut the thread" frame = Frame(tl) frame.grid() canvas = Canvas(frame, width=64, height=64) canvas.grid(row=2, column=0) canvas.create_rectangle(0, 0, 65, 65, fill=newColor) msgbody = Label( frame, text= "There is the moment to %s. Resume the current job after change." % msg) msgbody.grid(row=1, column=0, sticky=N) okbttn = Button(frame, text="OK", command=lambda: tl.destroy(), width=10) okbttn.grid(row=2, column=2)
def JobFinished(self, messagePopup=True): self.isJobRunning = False self.isJobPaused = False self.lastSendCommandIndex = -1 self.lastMove = None self.distanceTraveled = 0 self.currentToolChange = 0 self.currentToolPoint = 0 self.currentColor = 'black' self.toolPointsLabel.config( text="%d/%d" % (self.currentToolPoint, self.toolPointsTotal)) self.toolChangesLabel.config( text="%d/%d" % (self.currentToolChange, self.toolChangesTotal)) self.UpdateTimeEstLabel() self.startButton.config(text="Start job") self.status.config(text="Job finished") timeTaken = time.time() - self.start # non blocking popup messagebox if messagePopup: tl = Toplevel(root) # this pop-up is always on top and other windows are deactivated tl.attributes('-topmost', 'true') tl.title("Job finished") tl.grab_set() frame = Frame(tl) frame.grid() Label(frame, text='Current job is finished and took %s.' % time.strftime("%H hours, %M minutes, %S seconds", time.gmtime(timeTaken))).grid(row=0, column=0, sticky=N) Button(frame, text="OK", command=lambda: tl.destroy(), width=10).grid(row=1, column=0)
def getDelayCoordinates(self): try: self.root.iconify() top = Toplevel() top.geometry("+%d+%d" % (0, 0)) top.title("Counter") top.attributes('-alpha', 0.5) v = Tkinter.IntVar() ttk.Label(top, text="**hover mouse to the object you want to add", font=('Arial', 8)).pack() text = ttk.Label(top, textvariable=v) text.config(font=("Courier", 50)) text.pack() for i in range(5, -1, -1): v.set(i) text.update() time.sleep(1) top.destroy() self.SelDriver.set_webElement(PYAUTO.position()) self.createAttributePanel('delayadd') except AttributeError: messagebox.showinfo( 'Driver Not Initiated', 'Driver is not initiated.\nPlease make sure browser is Launched using tool.' )
class ProgressWindow: def __init__(self, parent, msg): self.parent = parent self.msg = msg self.window = None def start(self): self.window = Toplevel(self.parent.window) self.window.protocol('WM_DELETE_WINDOW', do_nothing) bar = Progressbar(self.window, orient=tk.HORIZONTAL, length=200, mode='indeterminate') label = Label(self.window, text=self.msg) self.window.title('Proszę czekać') self.window.geometry('300x50') #self.window.lift(aboveThis=self.parent.window) self.window.attributes("-topmost", True) label.pack(side=tk.TOP) bar.pack(side=tk.TOP) bar.start(10) self.window.grab_set() def destroy(self): self.window.grab_release() self.window.destroy()
def ask_for_object_classes(self): window = Toplevel(self.root) window.wm_title("Choose object classes to detect?") window.resizable(width=False, height=False) # instruct.geometry('{}x{}'.format(500, 100)) window.geometry('{}x{}'.format(200, 320)) # time.config(bg='lightgreen') window.attributes('-topmost', True) label1 = Label(window, text="Choose object classes to detect?") label1.pack(side="top", padx="10", pady="5") self.object_classes_to_detect = {key:IntVar(value=value) for key, value in self.object_classes_to_detect.items()} for key, value in self.object_classes_to_detect.items(): c = Checkbutton(window, text = key, variable = value, onvalue = 1, offvalue = 0) c.select() c.pack(side="top", anchor=W, padx="10", pady="5") btn1 = Button(window, text="Save", command=lambda *args: self.set_classes(window)) btn1.pack(side="top", fill="both", expand="yes", padx="10", pady="5") self.root.wait_window(window)
def addCutomProperty(self): addPropRow = 0 customAttributeWindow = Toplevel() customAttributeWindow.geometry("300x100") customAttributeWindow.attributes("-topmost", True) customAttributeWindow.title("Add Property") customAttributeWindow.grid_columnconfigure(1, weight=1) ttk.Label(customAttributeWindow, text='Property Name:', justify='left').grid(column=0, row=addPropRow, padx=5, pady=5, sticky='w') PropertyType = Entry(customAttributeWindow) PropertyType.grid(column=1, row=addPropRow, sticky='we') ttk.Label(customAttributeWindow, text='Property Value:', justify='left').grid(column=0, row=addPropRow + 1, padx=5, pady=5, sticky='w') PropertyValue = Entry(customAttributeWindow) PropertyValue.grid(column=1, row=addPropRow + 1, sticky='we') AddPropButton = ttk.Button(customAttributeWindow, text='Add Property') AddPropButton.grid(row=addPropRow + 2, column=1, padx=5, pady=10, sticky='w') currentItem = self.tree.focus() AddPropButton['command'] = lambda: self.POMTreeView.addProperty( self.tree, currentItem, customAttributeWindow)
class MessageModal(Toplevel): def __init__(self, root, time_label_var, modal_should_close): super().__init__(root, bg="green") self.modal_should_close = modal_should_close self.set_up_modal_attributes() self.create_widgets(time_label_var) self.bind_hide_events() self.hide() def set_up_modal_attributes(self): # settup the semitransparent background self.wm_attributes("-alpha", 0.3, "-fullscreen", True) self.wm_overrideredirect(True) # hide from taskbar # setting up the top layer in front of the background self.container = Toplevel(self, bg='magenta') self.container.wm_attributes("-fullscreen", True, "-alpha", 0.95, "-transparentcolor", 'magenta') self.container.overrideredirect(True) # hide from taskbar def create_widgets(self, time_label_var): frame_bg_color = "#111" self.frame = Frame(self.container, bg=frame_bg_color) self.frame.place(relx=.5, rely=.5, anchor="center", width=440, height=210) self.time_label = Label(self.frame, textvariable=time_label_var, bg=frame_bg_color, foreground="white", font=("Cookie", 75)) self.time_label.place(relx=.5, rely=.43, anchor="center") caption = Label(self.frame, text="Time to take a break.", bg=frame_bg_color, foreground="white", font=("Century Gothic", 13)) caption.place(relx=.5, rely=.7, anchor="center") def bind_hide_events(self): hide = lambda _: self.hide() self.bind("<Escape>", hide) self.bind("<space>", hide) self.container.bind("<Escape>", hide) self.container.bind("<space>", hide) def show(self): self.focus_set() self.deiconify() self.container.deiconify() self.attributes("-topmost", True, "-topmost", False) self.container.attributes("-topmost", True) def hide(self): self.withdraw() self.container.withdraw()
class SearchBox(Entry): def __init__(self, master=None, callback=None, lines=8, cnf={}, **kw): super().__init__(master, cnf, **kw) self.str_var = tk.StringVar() self["textvariable"] = self.str_var self.str_var.trace('w', self._callback) self.window = None self.lines = lines self.callback = callback self.master = master self.list_var = StringVar() self.prev_text = "" def _callback(self, *_): current_text = self.str_var.get() if current_text != self.prev_text: self.prev_text = current_text self.callback(current_text) def update(self, item_list): if item_list and self.window: self.list_var.set(item_list) elif not item_list and self.window: self._hide() elif item_list and not self.window: self._show() self.list_var.set(item_list) def _show(self): self.window = Toplevel() self.window.transient(self.master) self.window.overrideredirect(True) self.window.attributes("-topmost", 1) self.window.attributes("-alpha", 0.9) x = self.winfo_rootx() y = self.winfo_rooty() + self.winfo_height() + 6 self.window.wm_geometry("+%d+%d" % (x, y)) self._create_list() # self.window.mainloop() def _listbox_click(self, event): widget = event.widget cur_item = widget.get(widget.curselection()) self.str_var.set(cur_item) self._hide() def _create_list(self): list_box = Listbox(self.window, selectmode=tk.SINGLE, listvariable=self.list_var, height=self.lines) list_box.bind('<<ListboxSelect>>', self._listbox_click) list_box.pack(fill=tk.BOTH, expand=tk.YES) def _hide(self): if self.window: self.window.destroy() self.window = None
class PairsWindow(object): def __init__(self, parent): self.parent = parent self.window = Toplevel(parent.root) self.window.wm_title("Pairs") #self.window.resizable(width=False, height=False) #self.window.geometry('{}x{}'.format(250, 450)) self.window.attributes('-topmost', True) self.drawWidgets() def drawWidgets(self): label1 = Label(self.window, text="Choose pairs you want to delete:") label1.pack(side="top", padx="10", pady="5") self.tmp = OrderedDict() self.tmp = {str(key) + ': ' + str(self.parent.pixel_points[key]) + ' ' + str(self.parent.fix_points[key]):IntVar(value=0) for key, value in enumerate(self.parent.fix_points)} for key, value in self.tmp.items(): self.c = Checkbutton(self.window, text = str(key), variable = value, onvalue = 1, offvalue = 0) self.c.pack(side="top", anchor=W, padx="10", pady="5") btn1 = Button(self.window, text="Delete selected", command=lambda *args: self.del_sel(self.window)) btn1.pack(side="top", fill="both", padx="10", pady="5") btn2 = Button(self.window, text="Save pairs to disk", command=lambda *args: self.parent.save_pairs()) btn2.pack(side="top", fill="both", padx="10", pady="5") def update_gui(self): for widget in self.window.winfo_children(): widget.destroy() self.drawWidgets() def del_sel(self, window): tmp = 0 for i, key in enumerate(self.tmp.copy()): if self.tmp[key].get() == 1: i = i - tmp self.tmp.pop(key) #More lists than needed but too lazy to change it :) self.parent.pixel_points.pop(i) self.parent.fix_points.pop(i) self.parent.refPt.pop( (i * 2) ) self.parent.refPt.pop( (i * 2) ) self.parent.inter_line_counter -= 2 tmp += 1 self.update_gui() self.parent.draw()
class winlog(): """readonly modaless Toplevel log window class""" def __init__(self, root=None, title='Log Window'): self.win = Toplevel(root) self.win.title(title) self.win.geometry('800x600') self.frame_0 = tk.Frame(self.win) self.frame_0.pack(fill='both', expand=True) self.st = TkLog(master=self.frame_0, height=0) self.st.pack(fill='both', expand=True) self.frame_1 = tk.Frame(self.win) self.frame_1.pack(fill=tk.X) self.top = tk.Button(self.frame_1, text='Pin', command=self._pin) self.top.pack(side=tk.LEFT, padx=2, pady=2) self.win.bind('<FocusIn>', self._focusIn) self.win.bind('<FocusOut>', self._focusOut) self.pin = 0 # default is unpinned def _focusIn(self, event): self.win.attributes('-alpha', 1.0) def _focusOut(self, event): self.win.attributes('-alpha', 0.7) def _pin(self): if self.pin == 0: self.win.attributes('-topmost', True) self.pin = 1 self.top['text'] = 'Unpin' elif self.pin == 1: self.win.attributes('-topmost', False) self.pin = 0 self.top['text'] = 'Pin' def title(self, content, end='\n'): self.st.title(content, end) def log(self, content, end='\n'): self.st.log(content, end) def debug(self, content, end='\n'): self.st.debug(content, end) def warning(self, content, end='\n'): self.st.warning(content, end) def error(self, content, end='\n'): self.st.error(content, end) def critical(self, content, end='\n'): self.st.critical(content, end) def png(self, pngFile): self.st.png(pngFile) def gif(self, gifFile): self.st.gif(gifFile) def destroy(self): self.win.destroy()
def createPopup(self, title): # Variables popup = Toplevel() # Attributes popup.title(title) popup.geometry("350x150") popup.resizable(width = False, height = False) popup.configure(background = '#f2f2f2') popup.lift() popup.focus_force() popup.attributes('-topmost', True) return popup
class directCheckUI(): def __init__(self, owner, repo, branch): # calculation try: nCommit = getNCommit(owner, repo, branch) msg = f"Number of commit: {str(nCommit)}" except HTTPError: msg = "Given repository or branch not found" self.tk = Toplevel() self.tk.focus_set() self.tk.geometry('260x150') centerWindow(self.tk) self.tk["bg"] = COLORs['bg'] self.tk.attributes("-alpha", 0.95) # apearance Label(self.tk, text=f"{owner}/{repo}", bg=COLORs['bg'], font=Font(root=self.tk, family="Helvetica", size=13), fg=COLORs['txt']).place(anchor=N, x=130, y=15) Label(self.tk, text=branch, bg=COLORs['bg'], font=Font(root=self.tk, family="Helvetica", size=11), fg=COLORs['txt']).place(anchor=N, x=130, y=35) Label(self.tk, text=msg, bg=COLORs['bg'], font=Font(root=self.tk, family="Helvetica", size=11), fg=COLORs['txt']).place(anchor=N, x=130, y=65) self.btn = Button(self.tk, text="Close", command=(lambda: self.destroyWindow()), bg=COLORs['frmLine'], fg=COLORs['txt'], relief=FLAT, width=5, height=1, font=Font(root=self.tk, family="Helvetica", size=11), activebackground=COLORs['frmLine'], activeforeground=COLORs['txt']) batchBindEvent([self.tk, self.btn], effect=bindPressButtonEffect, target=self.btn, root=self.tk) self.btn.place(anchor=N, x=130, y=105) def destroyWindow(self): self.tk.destroy()
def __init__(self, master, title="guizero", width=800, height=480, layout="auto", bg="#ffffff", visible=True): description = "[Window] oject" self._modal = False tk = Toplevel(master.tk) tk.attributes("-fullscreen", True) super(Window, self).__init__(master, tk, description, title, width, height, layout, bg, visible)
class newScatterer: """ This is a pop-up window that is called when the user wants to create a new scatterer. """ def __init__(self, parent, controller): """ Parameters ---------- parent : An instance of a View object that contains a combobox, called cbox. controller : An instance of a Controller class. Returns ------- None. """ self.parent = parent self.controller = controller self.bcolor = 'grey' self.bthickness = 0 padding = 15 self.window = Toplevel(padx=padding, pady=padding) title = 'New Scatterer' self.window.wm_title(title) self.window.attributes("-topmost", True) self.header = tk.Label(self.window, text = 'Enter a name for the scatterer.') self.header.pack(side=TOP) self.name = StringVar() self.name_entry = tk.Entry(self.window, width = 20, textvariable = self.name) self.name_entry.pack(side=TOP) self.done = tk.Button(self.window, text='Done', command = self.Done) self.done.pack(side=TOP) self.name_entry.focus() def Done(self): name = self.name.get() self.controller.newScatterer(name) self.parent.cbox.set(name) self.controller.setCurrentScatterer(name) self.window.destroy()
class GressBar(): def __init__(self): self.tip = '' self.isLoop = False def start(self, title='下载Jira', lableTxt='任务正在运行中,请稍等……', ico=None): height = 150 width = 300 self.master = Toplevel() self.master.protocol("WM_DELETE_WINDOW", lambda: print('休想关闭')) setTitleIco(self.master, title, ico) self.master.attributes('-topmost', True) top = self.master overrideredirect = False top.overrideredirect(overrideredirect) top.title(title) Label(top, text=lableTxt, fg="green").pack(pady=5) prog = ttk.Progressbar(top, mode='indeterminate', length=200) prog.pack(pady=13, padx=35) prog.start() self.tipLable = tk.Label(self.master, text=self.tip, fg="green") self.tipLable.pack(pady=14) top.resizable(False, False) top.update() screenwidth = self.master.winfo_screenwidth() screenheight = self.master.winfo_screenheight() alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2) top.geometry(alignstr) self.isLoop = True self.start = time.clock() logUtils.debug('任务开始') top.mainloop() def updateMsg(self, msg: str): self.tip = msg if self.isLoop and hasattr(self, 'tipLable'): self.tipLable.config(text=msg) def quit(self): if self.isLoop: self.end = time.clock() logUtils.debug('任务结束 --- 使用时间({})'.format( toolUtils.getUsedTimeStr(self.start, self.end))) self.master.destroy() self.master = None
def ask_for_ref_coordinates(self): window = Toplevel(self.root) window.wm_title("Enter ref coordinates") window.resizable(width=False, height=False) window.geometry('{}x{}'.format(250, 300)) window.attributes('-topmost', True) label1 = Label(window, text="lat \n (top left corner of rectangle)") label1.pack(side="top", padx="10", pady="5") e2 = Entry(window) e2.config(width=10) e2.insert(END, self.lat_top_left) e2.pack(side="top", padx="10", pady="5") label2 = Label(window, text="long \n (top left corner of rectangle)") label2.pack(side="top", padx="10", pady="5") e3 = Entry(window) e3.config(width=10) e3.insert(END, self.long_top_left) e3.pack(side="top", padx="10", pady="5") label3 = Label(window, text="lat \n (bottom right corner of rectangle)") label3.pack(side="top", padx="10", pady="5") e4 = Entry(window) e4.config(width=10) e4.insert(END, self.lat_bottom_right) e4.pack(side="top", padx="10", pady="5") label4 = Label(window, text="long \n (bottom right corner of rectangle)") label4.pack(side="top", padx="10", pady="5") e5 = Entry(window) e5.config(width=10) e5.insert(END, self.long_bottom_right) e5.pack(side="top", padx="10", pady="5") btn1 = Button(window, text="Set", command=lambda *args: self.set_reference_coordinates( e2.get(), e3.get(), e4.get(), e5.get(), window)) btn1.pack(side="top", fill="both", expand="yes", padx="10", pady="5") self.root.wait_window(window)
def ask_for_tracking_options(self): window = Toplevel(self.root) window.wm_title("Tracking options") window.resizable(width=False, height=False) window.geometry('{}x{}'.format(300, 400)) window.attributes('-topmost', True) label1 = Label(window, text="Choose tracking methods?") label1.grid(row=0, sticky=W) tmp = 0 for i, (key, value) in enumerate(self.tracking_methods.items()): c = Checkbutton(window, text=key, variable=value, onvalue=1, offvalue=0) c.grid(row=i + 1, sticky=W) tmp += 1 Label(window, text="CamShift Grouping (0/1):").grid(row=tmp + 1, sticky=W) e6 = Entry(window) e6.insert(5, self.meanShift) e6.grid(row=tmp + 1, column=1) Label(window, text="CamShift max_iter:").grid(row=tmp + 2, sticky=W) e7 = Entry(window) e7.insert(5, self.max_iter) e7.grid(row=tmp + 2, column=1) Label(window, text="CamShift min_movement:").grid(row=tmp + 3, sticky=W) e8 = Entry(window) e8.insert(5, self.min_movement) e8.grid(row=tmp + 3, column=1) btn1 = Button(window, text="Set", command=lambda *args: self.set_tracking_methods( window, e7.get(), e8.get(), e6.get())) btn1.grid(row=tmp + 4) self.root.wait_window(window)
def button(): def loop(): if e.p % 2 == 0: var.root.withdraw() B.geometry(f"10x10+{var.ws-10}+{var.hs-10}") e.p += 1 else: var.root.deiconify() B.geometry(f"10x10+{var.x - 10}+{var.hs-10}") e.p += 1 B = Toplevel() B.geometry(f"10x10+{var.x - 10}+{var.hs-10}") b1 = Button(B, text="", command=loop, bg="#324959", fg="#324959", relief="flat", highlightbackground="#324959") b1.pack() B.attributes("-topmost", True) B.overrideredirect(True)
def set_size(game_screen): popup = Toplevel() popup.title("Enter size") popup.attributes('-topmost', True) frame = Frame(popup) frame.grid(row=0, column=0) msg = Label(frame, text="New grid size (number between 5 and 25):", font=("Helvetica", 10)) msg.grid(row=0, column=0) def validate(value, action_type): if action_type == '1': if not value.isdigit(): return False return True entry = Entry(frame, validate='key') entry['validatecommand'] = (entry.register(validate), '%P', '%d') entry.grid(row=0, column=1) def submit(): size = int(entry.get()) if size in range(5, 26): game_screen.resize((size, size)) popup.destroy() else: entry.delete(0, 10) messagebox.showerror('Error', 'Number not in range.') submit_btn = Button(frame, height=1, width=5, text='Submit', font=('Helvetica', 10), command=submit) submit_btn.grid(row=0, column=2)
def reset_server(): '''Restarts Choosing of CSV Files''' global tempdir, tempdir2, opened, gui, httpd threading.Thread(target=httpd.shutdown, daemon=True).start() threading.Thread(target=httpd.server_close, daemon=True).start() gui = Toplevel() gui.title('PythonGUI') #Title gui.iconbitmap('resources/snake.ico') #GUI Icon gui.minsize(500, 540) #Size of GUI gui.attributes('-topmost', True) #Set GUI to always be the topmost window opened = [0, 0] tempdir, tempdir2 = '', '' photo = PhotoImage(file="resources/gui.png") #Logo label_five = Label(gui, image=photo).grid(pady=10) btn_one = Button(gui, text="Choose 1st CSV file", command=lambda: open_file('1')).grid( pady=4) #CSV Selection btn_two = Button(gui, text="Choose 2nd CSV file", command=lambda: open_file('2')).grid(pady=4) browsers = { 'Firefox': "firefox", 'Chrome': "chrome", 'Opera': "opera", 'Iexplore': "iexplore" } items = StringVar(value=tuple(sorted(browsers.keys()))) listbox = Listbox(gui, listvariable=items, width=40, height=5) #Browser Selection listbox.grid(column=0, row=4, rowspan=6, pady=10) selectButton = Button(gui, text='Select Browser', underline=0, command=lambda: selection(listbox.selection_get())) selectButton.grid(pady=10) gui.mainloop()
def createAttributePanel(self, actionType=None, event=None): if actionType != 'delayadd': self.SelDriver.set_webElement((event.x, event.y), self.ScreenCoverWindow) attributePanelWindow = Toplevel() attributePanelWindow.geometry("600x500") attributePanelWindow.attributes('-topmost', True) attributePanelWindow.title("Object Properties") attributePanelWindow.grid_columnconfigure(0, weight=1) attributePanelWindow.grid_rowconfigure(0, weight=1) top = ttk.Frame(attributePanelWindow) top.grid(column=0, row=0, sticky='nsew') top.grid_columnconfigure(0, weight=1, uniform="group1") top.grid_columnconfigure(1, weight=1, uniform="group1") top.grid_rowconfigure(0, weight=1) self.attributeTreeFrame = Frame(top, borderwidth=1, relief="solid") self.attributetreeValues = Frame(top, borderwidth=1, relief='solid') self.attributeTreeFrame.grid_rowconfigure(0, weight=1) self.attributeTreeFrame.grid_columnconfigure(0, weight=1) self.attributeTreeFrame.grid(row=0, column=0, sticky='nsew') self.attributetreeValues.grid(row=0, column=1, sticky="nsew") footer = ttk.Frame(top, height=120) footer.grid(column=0, row=1, columnspan=2) ttk.Button(footer, text='Cancel', command=attributePanelWindow.destroy).grid(column=2, row=1, padx=5, pady=10) ttk.Button(footer, text='Add Object', command=lambda: self.updatePOMTree( attributePanelWindow, self.ObjectPropertyTree.getObjectDict())).grid(column=1, row=1, padx=5, pady=10) self.createAttributeTree(self.SelDriver.attributeList, actionType)
def ask_for_export_granularity(self): window = Toplevel(self.root) window.wm_title("Choose export granularity?") window.resizable(width=False, height=False) # instruct.geometry('{}x{}'.format(500, 100)) window.geometry('{}x{}'.format(225, 200)) # time.config(bg='lightgreen') window.attributes('-topmost', True) label1 = Label(window, text="Choose export granularities in minutes") label1.pack(side="top", padx="10", pady="5") e2 = Entry(window) e2.config(width=10) e2.insert(END, self.export_granularity) e2.pack(side="top", padx="10", pady="5") e3 = Entry(window) e3.config(width=10) e3.insert(END, self.export_granularity2) e3.pack(side="top", padx="10", pady="5") e4 = Entry(window) e4.config(width=10) e4.insert(END, self.export_granularity3) e4.pack(side="top", padx="10", pady="5") var = IntVar(value=int(self.export_raw)) c = Checkbutton(window, text = 'Export raw data too?', variable = var, onvalue = 1, offvalue = 0) c.pack(side="top", anchor=W, padx="10", pady="5") btn1 = Button(window, text="Save", command=lambda *args: self.set_export_granularity(e2.get(), e3.get(), e4.get(),var.get(), window)) btn1.pack(side="top", fill="both", expand="yes", padx="10", pady="5") self.root.wait_window(window)
class AutoSearchCombobox(Entry): def __init__(self, master: Widget, values: Optional[Iterable[str]] = None, height: Optional[int]=None, **kwargs): super().__init__(master, **kwargs) self._tl = Toplevel(self, takefocus=False, relief=GROOVE, borderwidth=1) self._tl.wm_overrideredirect(True) self._lb = ScrolledListbox(self._tl, width=kwargs.pop('width', None), height=height, selectmode=SINGLE) self.values = values self._lb.pack(expand=True, fill=BOTH) self._hide_tl() self.winfo_toplevel().focus_set() self.bind('<KeyRelease>', self._handle_keyrelease) self.bind('<FocusOut>', self._handle_focusout) self.bind('<KeyPress>', self._handle_keypress) #toplevel bindings cfg_handler = self.winfo_toplevel().bind('<Configure>', self._handle_configure, add="+") self.bind('<Destroy>', lambda __, cfg_handler=cfg_handler: self._unbind_my_configure(cfg_handler)) def _unbind_my_configure(self, cfg_handler): """Internal function. Allows for JUST this widget's associated callback. Getting around tkinter bug""" root_tl = self.winfo_toplevel() if not cfg_handler: root_tl.tk.call('bind', self._w, '<Configure>', '') return func_callbacks = root_tl.tk.call( 'bind', root_tl._w, '<Configure>', None).split('\n') new_callbacks = [ l for l in func_callbacks if l[6:6 + len(cfg_handler)] != cfg_handler] root_tl.tk.call('bind', root_tl._w, '<Configure>', '\n'.join(new_callbacks)) root_tl.deletecommand(cfg_handler) @property def values(self): """ Gets the values """ try: return self.__values except AttributeError: self.values = () return self.values @values.setter def values(self, values: Optional[Iterable]): """ Sorts and sets the values """ self.__values = tuple(sorted(values)) if values is not None else tuple() self._lb.insert(END, *self.values) self._lb.selection_clear(0, END) self._lb.selection_set(0) self._lb.activate(0) @property def _lb_current_selection(self) -> str: """ Returns the current selection in the listbox """ try: sel = self._lb.curselection()[0] except IndexError: return None return self._lb.get(sel) def _set_lb_index(self, index): self._lb.selection_clear(0, END) self._lb.selection_set(index) self._lb.activate(index) self._lb.see(index) @property def text_after_cursor(self) -> str: """ Gets the entry text after the cursor """ contents = self.get() return contents[self.index(INSERT):] @property def dropdown_is_visible(self): return self._tl.winfo_ismapped() def _handle_keypress(self, event: Event): if 'Left' in event.keysym: if self.dropdown_is_visible: self._hide_tl() return 'break' else: return elif (('Right' in event.keysym and self.text_after_cursor == '') or event.keysym in ['Return', 'Tab']) and self.dropdown_is_visible: #Completion and block next action self.delete(0, END) self.insert(0, self._lb_current_selection) self._hide_tl() return 'break' def _handle_keyrelease(self, event: Event): if 'Up' in event.keysym and self.dropdown_is_visible: previous_index = self._lb.index(ACTIVE) new_index = max(0, self._lb.index(ACTIVE) - 1) self._set_lb_index(new_index) if previous_index == new_index: self._hide_tl() return if 'Down' in event.keysym: if self.dropdown_is_visible: current_index = self._lb.index(ACTIVE) new_index = min(current_index + 1, self._lb.size() - 1) self._set_lb_index(new_index) return 'break' if not self.dropdown_is_visible and self._lb.size() > 0: self._show_tl() if len(event.keysym) == 1 or ('Right' in event.keysym and self.text_after_cursor == '') or event.keysym in ['BackSpace']: if self.get() != '': new_values = [value for value in self.values if value.lower( ).startswith(self.get().lower())] else: new_values = self.values self._lb.delete(0, END) self._lb.insert(END, *new_values) self._set_lb_index(0) if self._lb.size() < 1 or self.get() == self._lb_current_selection: self._hide_tl() else: self._show_tl() def _handle_focusout(self, event: Event): def cf(): if self.focus_get() != self._tl and self.focus_get() != self._lb: self._hide_tl() else: self.focus_set() self.after(1, cf) def _handle_configure(self, event: Event): if self._tl.winfo_ismapped(): self._update_tl_pos() def _show_tl(self) -> None: if self._tl.winfo_ismapped() == False: self._update_tl_pos() self._tl.deiconify() self._tl.attributes("-topmost", True) def _update_tl_pos(self) -> None: self._tl.geometry('+{}+{}'.format(self.winfo_rootx(), self.winfo_rooty() + self.winfo_height() - 1)) def _hide_tl(self) -> None: self._tl.withdraw()
class myApp: def __init__(self): self.root = Tk() style = ttk.Style() style.configure("Treeview.Heading", font=(None, 11), background="green") self.config = ST.Setting(self.root) self.SelDriver = SeleniumProcessor.SeleniumDriver(self.config) self.POMTreeView = TreeProcessor.POMTree(self.config) self.XML = XMLProcessor.XML() self.treeFrame = None self.tree = None self.treeValues = None self.ScreenCoverWindow = None self.root.title("POM Manager") self.root.geometry('700x600') #MENU SECTION : to create Menu # File Menu menu = Menu(self.root) self.root.config(menu=menu) filemenu = Menu(menu) menu.add_cascade(label="File", menu=filemenu) filemenu.add_command(label="Create New POM..", command=self.NewFile) filemenu.add_command(label="Open POM...", command=self.OpenFile) filemenu.add_command(label="Save POM...", command=self.SaveFile) filemenu.add_command(label="Save as POM...", command=self.SaveFileAs) filemenu.add_separator() filemenu.add_command(label="Exit", command=self.root.destroy) toolmenu = Menu(menu) menu.add_cascade(label="Tool", menu=toolmenu) toolmenu.add_command(label="Settings", command=self.Settings) helpmenu = Menu(menu) menu.add_cascade(label="Help", menu=helpmenu) helpmenu.add_command(label="About...", command=self.About) self.root.grid_columnconfigure(0, weight=1) self.root.grid_rowconfigure(1, weight=1) top = ttk.Frame(self.root, height=200) top.grid_columnconfigure(1, weight=1) top.grid(column=0, row=0, pady=10, sticky='nsew') bottom = ttk.Frame(self.root) bottom.grid(column=0, row=1, sticky='nsew') bottom.grid_columnconfigure(0, weight=1, uniform="group1") bottom.grid_columnconfigure(1, weight=1, uniform="group1") bottom.grid_rowconfigure(0, weight=1) footer = ttk.Frame(bottom, height=120) Label(top, text='Enter Base URL :').grid(column=0, row=0) self.txtURL = Entry(top) self.txtURL.grid(column=1, row=0, sticky='we') browserCombo = ttk.Combobox(top, values=['Chrome', 'IE', 'Edge', 'FireFox'], state='readonly') browserCombo.set('Chrome') browserCombo.grid(column=2, row=0, padx=5) self.Launchbtn = ttk.Button( top, text="Launch", command=lambda: self.SelDriver.LaunchBrowser( browserCombo.get(), self.txtURL.get())) self.Launchbtn.grid(column=1, row=1, pady=5) self.root.bind("<Control-s>", lambda event: self.XML.saveXML(self.POMTreeView)) self.AddNewObjectButton = ttk.Button( footer, text='Add New Object ', command=lambda: self.enable_mouseposition()) self.AddNewObjectButton.grid(column=0, row=1, padx=5, pady=20) self.ManuallyAddobject = ttk.Button( footer, text='Add Object Manually', command=lambda: self.addobjectPropertiesManually()) self.ManuallyAddobject.grid(column=2, row=1, padx=5, pady=20) self.savebutton = ttk.Button( footer, text='Save', command=lambda: self.XML.saveXML(self.tree, self.POMTreeView)) self.savebutton.grid(column=3, row=1, padx=5, pady=20) self.AddToPageButton = ttk.Button( footer, text='Add With Delay', command=lambda: self.getDelayCoordinates()) self.AddToPageButton.grid(column=1, row=1, padx=5, pady=20) self.CancelButton = ttk.Button(footer, text='Cancel', command=self.root.destroy) self.CancelButton.grid(column=4, row=1, padx=5, pady=20) self.treeFrame = Frame(bottom, borderwidth=1, relief="solid") self.treeValues = Frame(bottom, borderwidth=1, relief="solid") self.treeFrame.grid_rowconfigure(0, weight=1) self.treeFrame.grid_columnconfigure(0, weight=1) self.treeFrame.grid(row=0, column=0, sticky='nsew') self.treeValues.grid(row=0, column=1, sticky='nsew') bottom.grid_rowconfigure(0, weight=1) footer.grid(column=0, row=1, columnspan=2) mainloop() try: self.SelDriver.quit() except AttributeError: None def NewFile(self): files = [('ORFile', '*.xml.')] file = asksaveasfile(title="Select folder", filetypes=files, defaultextension=files) self.XML.filePath = file.name self.XML.fileName = ((file.name).split('/')[-1]).split('.')[0] self.createPOMTree('newfile') def OpenFile(self): filePath = filedialog.askopenfilename() if len(filePath) > 4: self.XML = XMLProcessor.XML(filePath) if self.tree != None: self.tree.destroy() self.createPOMTree() self.AddToPageButton['state'] = 'normal' def About(self): print('This is a simple example of a menu!') def SaveFile(self): self.XML.saveXML(self.tree, self.POMTreeView) def SaveFileAs(self): self.XML.saveXML(self.tree, self.POMTreeView, 'newfile') #======================================================================= # self.tree.heading('#0', text=self.XML.fileName) #======================================================================= def Settings(self): self.config.displaySettingPanel() def cancelAddObject(self, topWindow): topWindow.destroy() def getDelayCoordinates(self): try: self.root.iconify() top = Toplevel() top.geometry("+%d+%d" % (0, 0)) top.title("Counter") top.attributes('-alpha', 0.5) v = Tkinter.IntVar() ttk.Label(top, text="**hover mouse to the object you want to add", font=('Arial', 8)).pack() text = ttk.Label(top, textvariable=v) text.config(font=("Courier", 50)) text.pack() for i in range(5, -1, -1): v.set(i) text.update() time.sleep(1) top.destroy() self.SelDriver.set_webElement(PYAUTO.position()) self.createAttributePanel('delayadd') except AttributeError: messagebox.showinfo( 'Driver Not Initiated', 'Driver is not initiated.\nPlease make sure browser is Launched using tool.' ) def enable_mouseposition(self, actionType=None): try: driver = self.SelDriver.driver driver.switch_to.window( driver.window_handles[len(driver.window_handles) - 1]) self.root.after(100, self.get_WebObject(actionType)) except AttributeError: Tkinter.messagebox.showinfo( 'Driver Not Initiated', 'Driver is not initiated. \nPlease make sure browser is launched using tool.' ) def get_WebObject(self, actionType): self.ScreenCoverWindow = Toplevel() self.root.iconify() self.ScreenCoverWindow.attributes('-topmost', True) self.ScreenCoverWindow.title("Object Properties") self.ScreenCoverWindow.attributes('-alpha', 0.2) self.ScreenCoverWindow.attributes("-fullscreen", True) self.ScreenCoverWindow.focus_force() self.ScreenCoverWindow.bind( "<Button-1>", lambda event: self.createAttributePanel(actionType, event)) def createAttributePanel(self, actionType=None, event=None): if actionType != 'delayadd': self.SelDriver.set_webElement((event.x, event.y), self.ScreenCoverWindow) attributePanelWindow = Toplevel() attributePanelWindow.geometry("600x500") attributePanelWindow.attributes('-topmost', True) attributePanelWindow.title("Object Properties") attributePanelWindow.grid_columnconfigure(0, weight=1) attributePanelWindow.grid_rowconfigure(0, weight=1) top = ttk.Frame(attributePanelWindow) top.grid(column=0, row=0, sticky='nsew') top.grid_columnconfigure(0, weight=1, uniform="group1") top.grid_columnconfigure(1, weight=1, uniform="group1") top.grid_rowconfigure(0, weight=1) self.attributeTreeFrame = Frame(top, borderwidth=1, relief="solid") self.attributetreeValues = Frame(top, borderwidth=1, relief='solid') self.attributeTreeFrame.grid_rowconfigure(0, weight=1) self.attributeTreeFrame.grid_columnconfigure(0, weight=1) self.attributeTreeFrame.grid(row=0, column=0, sticky='nsew') self.attributetreeValues.grid(row=0, column=1, sticky="nsew") footer = ttk.Frame(top, height=120) footer.grid(column=0, row=1, columnspan=2) ttk.Button(footer, text='Cancel', command=attributePanelWindow.destroy).grid(column=2, row=1, padx=5, pady=10) ttk.Button(footer, text='Add Object', command=lambda: self.updatePOMTree( attributePanelWindow, self.ObjectPropertyTree.getObjectDict())).grid(column=1, row=1, padx=5, pady=10) self.createAttributeTree(self.SelDriver.attributeList, actionType) def createAttributeTree(self, attrsList, processType=None): self.attributeTree = ttk.Treeview(self.attributeTreeFrame) self.yscrollbar = Util.AutoScrollbar(self.attributeTreeFrame, orient='vertical', command=self.attributeTree.yview) self.attributeTree.configure(yscrollcommand=self.yscrollbar.set) self.attributeTree.grid(row=0, column=0, sticky='nsew') self.yscrollbar.grid(row=0, column=1, sticky='ns') self.ObjectPropertyTree = TreeProcessor.ObjectPropertyTree( self.attributeTree, attrsList, processtype=processType) self.attributeTree.bind( "<<TreeviewSelect>>", lambda event: self.displayProperties( self.attributetreeValues, self.ObjectPropertyTree.getObjectDict())) def displayProperties(self, attributes, newObjectTreeDict, actiontype=None): propertyNum = 0 for widget in attributes.winfo_children(): widget.destroy() currentItem = self.attributeTree.focus() currObject = newObjectTreeDict[currentItem] attributes.grid_columnconfigure(1, weight=1) ttk.Label(attributes, text='Display Name', justify='left').grid(column=0, row=0, padx=5, pady=1, sticky='w') DefaultVal = StringVar(attributes, value=currObject.DisplayName) Entry(attributes, textvariable=DefaultVal).grid(column=1, row=0, padx=5, pady=1, sticky='we', columnspan=1) for oProperty in currObject.propertyList: isPropSelected = oProperty.Selected isUsed = Tkinter.IntVar() propertyCheckButton = ttk.Checkbutton(attributes, text=oProperty.propertyName, variable=isUsed) propertyCheckButton.is_selected = isUsed propertyCheckButton.grid(column=0, row=propertyNum + 1, padx=5, pady=1, sticky='w') DefaultVal = StringVar(attributes, value=oProperty.Value) PropertyVal = Entry(attributes, textvariable=DefaultVal) PropertyVal.grid(column=1, row=propertyNum + 1, padx=5, pady=1, sticky='we', columnspan=2) if isPropSelected == '1' or isPropSelected == 1: propertyCheckButton.var = isUsed propertyCheckButton.var.set(1) else: propertyCheckButton.var = isUsed propertyCheckButton.var.set(0) propertyNum = propertyNum + 1 UpdateButton = ttk.Button(attributes, text='Update') UpdateButton.grid(column=1, row=propertyNum + 1, padx=10, pady=20, sticky='w') if actiontype == 'manual': AddChildButton = ttk.Button(attributes, text='Add child Object ') AddChildButton['command'] = lambda: self.AddChildToAttributeTree() AddChildButton.grid(column=0, row=propertyNum + 1, padx=10, pady=20, sticky='w') UpdateButton['command'] = lambda: self.UpdateProperties( self.scrollable_frame, currentItem) else: UpdateButton['command'] = lambda: self.UpdateProperties( self.attributetreeValues, currentItem) def UpdateProperties(self, treeVal, key): self.ObjectPropertyTree.updateObjectDict(treeVal, key) def updatePOMTree(self, propertyWindow, objDict, actionType=None): currItem = self.attributeTree.focus() objectToAdd = objDict[currItem] currObject = objectToAdd addToObject = '' objList = [currObject.ObjectID] if self.tree == None: self.createPOMTree() propertyWindow.attributes('-topmost', False) if self.tree.exists(currObject.ObjectID): messagebox.showinfo( 'Object Present with ID: =' + currObject.ObjectID, 'Object Present with ID: ' + currObject.ObjectID + '. \nPlease Change the Name or Update object Directly from Attribute Window' ) else: self.POMTreeView.treeDict[currObject.ObjectID] = currObject while currObject.ParentID != None and len(currObject.ParentID) > 0: if self.tree.exists(currObject.ParentID): addToObject = currObject.ParentID self.POMTreeView.treeDict[addToObject].childList.append( currObject) break else: currObject = objDict[currObject.ParentID] self.POMTreeView.treeDict[currObject.ObjectID] = currObject objList.insert(0, currObject.ObjectID) for childtree in objList: childObj = objDict[childtree] self.tree.insert(addToObject, 'end', iid=childObj.ObjectID, text=childObj.DisplayName) addToObject = childObj.ObjectID propertyWindow.destroy() Util.focusTree(self.tree, objectToAdd.ObjectID) print('Object to Focus :' + currObject.ObjectID) def AddChildToAttributeTree(self): for widget in self.scrollable_frame.winfo_children(): widget.destroy() self.addObjectIndentificationFields(self.attributeTree, self.scrollable_frame, 'child') def addobjectPropertiesManually(self): self.attributePanelWindow = Toplevel() self.attributePanelWindow.geometry("600x500") self.attributePanelWindow.attributes('-topmost', True) self.attributePanelWindow.title("Object Properties") self.attributePanelWindow.grid_columnconfigure(0, weight=1) self.attributePanelWindow.grid_rowconfigure(0, weight=1) top = ttk.Frame(self.attributePanelWindow) top.grid(column=0, row=0, sticky='nsew') top.grid_columnconfigure(0, weight=1, uniform="group1") top.grid_columnconfigure(1, weight=1, uniform="group1") top.grid_rowconfigure(0, weight=1) self.attributeTreeFrame = Frame(top, borderwidth=1, relief="solid") self.attributetreeValues = Frame(top, borderwidth=1, relief="solid") self.attributeTreeFrame.grid_rowconfigure(0, weight=1) self.attributeTreeFrame.grid_columnconfigure(0, weight=1) self.attributeTreeFrame.grid(row=0, column=0, sticky='nsew') self.attributetreeValues.grid_rowconfigure(0, weight=1) self.attributetreeValues.grid_columnconfigure(0, weight=1) self.attributetreeValues.grid(row=0, column=1, sticky='nsew') self.scrollable_frame = Util.ScrollableFrame(self.attributetreeValues, 'both') self.attributeTree = ttk.Treeview(self.attributeTreeFrame) self.attributeTree.grid(row=0, column=0, sticky="nsew") self.attributeTree.bind( "<<TreeviewSelect>>", lambda event: self.displayProperties( self.scrollable_frame, self.ObjectPropertyTree.getObjectDict(), 'manual')) footer = ttk.Frame(top, height=120) footer.grid(column=0, row=1, columnspan=2) ttk.Button(footer, text='Cancel', command=self.attributePanelWindow.destroy).grid(column=0, row=1, padx=5, pady=10) ttk.Button(footer, text='Add Object', command=lambda: self.updatePOMTree( self.attributePanelWindow, self.ObjectPropertyTree.getObjectDict())).grid(column=1, row=1, padx=5, pady=10) self.addObjectIndentificationFields(self.attributeTree, self.scrollable_frame) def addObjectIndentificationFields(self, objTree, Scrollableframe, objtype=None): objectTypeList = ['POM_Page'] if len( objTree.get_children()) == 0 else ['POM_frame', 'POM_Object'] ttk.Label(Scrollableframe, text='Object Type', justify='left').grid(column=0, row=0, padx=5, sticky='w') ObjectTypeCombo = ttk.Combobox(Scrollableframe, values=objectTypeList, state='readonly') ObjectTypeCombo.grid(column=1, row=0, sticky='we') ttk.Label(Scrollableframe, text='Display Name', justify="left").grid(column=0, row=1, padx=5, sticky='w') comboExample = ttk.Combobox(Scrollableframe, values=[]) comboExample.grid(column=1, row=1, sticky='we') ObjectTypeCombo.bind( "<<ComboboxSelected>>", lambda event: self.getObjectList( Scrollableframe, ObjectTypeCombo, comboExample)) self.addPropertywidget(Scrollableframe, 2, objtype) def getObjectList(self, Scrollableframe, ObjectTypeCombo, comboExample): listObjectName = [] if ObjectTypeCombo.get() == 'POM_Page': if self.tree != None: for child in self.tree.get_children(): listObjectName.append(child) comboExample['values'] = listObjectName def addPropertywidget(self, propertyWindow, addPropRow, objtype=None): ttk.Label(propertyWindow, text=' ', justify='left').grid(column=0, row=addPropRow, padx=5, sticky='w') ttk.Label(propertyWindow, text='Property Name:', justify='left').grid(column=0, row=addPropRow + 1, padx=5, sticky='w') PropertyType = Entry(propertyWindow) PropertyType.grid(column=1, row=addPropRow + 1, sticky='we') ttk.Label(propertyWindow, text='Property Value:', justify='left').grid(column=0, row=addPropRow + 2, padx=5, sticky='w') PropertyValue = Entry(propertyWindow) PropertyValue.grid(column=1, row=addPropRow + 2, sticky='we') AddPropButton = ttk.Button(propertyWindow, text='Add Property.. ') AddPropButton.grid(row=addPropRow + 3, column=0, padx=5, pady=5, sticky='e') AddPropButton['command'] = lambda: self.addAttribute( propertyWindow, addPropRow, objtype) buttonFrame = Frame(propertyWindow) buttonFrame.grid(column=0, row=addPropRow + 4, columnspan=2) if objtype == 'child': ttk.Button(buttonFrame, text='Add to Tree', command=lambda: self.AddManualobjectToTree( propertyWindow, objtype)).grid(column=0, row=0, padx=5, pady=20) else: ttk.Button(buttonFrame, text='Add to Tree', command=lambda: self.AddManualobjectToTree( propertyWindow)).grid(column=0, row=0, padx=5, pady=20) cancelbutton = ttk.Button( buttonFrame, text='Cancel ', command=lambda: self.refreshAddManualobjectPanel()) cancelbutton.grid(column=1, row=0, padx=5, pady=20) def refreshAddManualobjectPanel(self): for widget in self.scrollable_frame.winfo_children(): widget.destroy() if len(self.attributeTree.get_children()) > 0: currItem = self.attributeTree.focus() Util.focusTree(self.attributeTree, currItem) else: self.addObjectIndentificationFields(self.attributeTree, self.scrollable_frame) def addAttribute(self, propertyWindow, addProp, objtype=None): PropertyName = (propertyWindow.grid_slaves(addProp + 1, 1)[0]).get() PropertyVal = (propertyWindow.grid_slaves(addProp + 2, 1)[0]).get() v = Tkinter.IntVar() for i in range(addProp, addProp + 5): for w in propertyWindow.grid_slaves(row=i): w.grid_forget() c = Checkbutton(propertyWindow, text=PropertyName, variable=v) c.grid(column=0, row=addProp, padx=5, sticky='w') c.is_selected = v DefaultVal = StringVar(self.root, value=PropertyVal) Entry(propertyWindow, textvariable=DefaultVal).grid(column=1, row=addProp, sticky='we') self.addPropertywidget(propertyWindow, addProp + 1, objtype) def AddManualobjectToTree(self, treeManual, objtype=None): if (treeManual.grid_slaves( 0, 1)[0]).get() == '' or (treeManual.grid_slaves( 0, 1)[0]).get() == None or (treeManual.grid_slaves( 1, 1)[0]).get() == '' or (treeManual.grid_slaves( 1, 1)[0]).get() == None: messagebox.showinfo( 'Object Not Created', 'Please provide Object Name and at least one property to add object.' ) else: if objtype == 'child': currentItem = self.attributeTree.focus() currParentObj = self.ObjectPropertyTree.objectDict[currentItem] currObj = self.ObjectPropertyTree.createTreeObject( currParentObj)[1] else: self.ObjectPropertyTree = TreeProcessor.ObjectPropertyTree( self.attributeTree, treevals=treeManual) currObj = self.ObjectPropertyTree.createTreeObject()[1] Util.focusTree(self.attributeTree, currObj.ObjectID) def createPOMTree(self, processType=None): if self.tree != None: self.tree.destroy() self.tree = Util.scrollableTree(self.treeFrame, 'both') self.tree.heading('#0', anchor='w') self.tree.grid(row=0, column=0, sticky="nsew") if self.POMTreeView == None: print('IT IS NULL') self.POMTreeView.setTree(self.tree) if self.XML.filePath != None: self.POMTreeView.createTree(self.XML, self.tree, processType) self.tree.bind("<<TreeviewSelect>>", lambda event: self.displayObjectProperties(event)) def displayObjectProperties(self, currentItem=None): propertyNum = 1 for widget in self.treeValues.winfo_children(): widget.destroy() self.currentItem = self.tree.focus() self.POMTreeView.ORObject = self.currentItem currObject = self.POMTreeView.ORObject ttk.Label(self.treeValues, text='Display Name', justify='left').grid(column=0, row=0, padx=5, sticky='w') DefaultVal = StringVar(self.treeValues, value=currObject.DisplayName) Entry(self.treeValues, textvariable=DefaultVal, state='readonly').grid(column=1, row=0, sticky='we', columnspan=2) ttk.Label(self.treeValues, text='Object ID', justify='left').grid(column=0, row=propertyNum, padx=5, sticky='w') DefaultVal = StringVar(self.treeValues, value=currObject.ObjectID) Entry(self.treeValues, textvariable=DefaultVal, state='readonly').grid(column=1, row=propertyNum, sticky='we', columnspan=2) self.treeValues.grid_columnconfigure(1, weight=1) for oProperty in currObject.propertyList: isPropSelected = oProperty.Selected isUsed = Tkinter.IntVar() propertyCheckButton = ttk.Checkbutton(self.treeValues, text=oProperty.propertyName, variable=isUsed, state='disabled') propertyCheckButton.is_selected = isUsed propertyCheckButton.grid(column=0, row=propertyNum + 1, padx=5, sticky='w') DefaultVal = StringVar(self.treeValues, value=oProperty.Value) PropertyVal = Entry(self.treeValues, textvariable=DefaultVal, state='readonly') PropertyVal.grid(column=1, row=propertyNum + 1, sticky='we', columnspan=2) if isPropSelected == '1' or isPropSelected == 1: propertyCheckButton.var = isUsed propertyCheckButton.var.set(1) else: propertyCheckButton.var = isUsed propertyCheckButton.var.set(0) propertyNum = propertyNum + 1 EditButton = ttk.Button(self.treeValues, text=' Edit ') EditButton['command'] = lambda: self.editProperties( EditButton, propertyNum + 1) EditButton.grid(column=1, row=propertyNum + 1, padx=10, pady=20, sticky='w') def editProperties(self, EditButton, propertyNum): EditButton['text'] = 'Update' EditButton.grid(column=2) ttk.Button(self.treeValues, text='Add Custom Property', command=lambda: self.addCutomProperty()).grid( column=1, row=propertyNum, pady=20, sticky='w') for widget in self.treeValues.winfo_children(): widget['state'] = 'normal' self.treeValues.grid_slaves(1, 1)[0]['state'] = 'readonly' self.isPropertySaved = False EditButton['command'] = lambda: self.updateObjectProperty(EditButton) def addCutomProperty(self): addPropRow = 0 customAttributeWindow = Toplevel() customAttributeWindow.geometry("300x100") customAttributeWindow.attributes("-topmost", True) customAttributeWindow.title("Add Property") customAttributeWindow.grid_columnconfigure(1, weight=1) ttk.Label(customAttributeWindow, text='Property Name:', justify='left').grid(column=0, row=addPropRow, padx=5, pady=5, sticky='w') PropertyType = Entry(customAttributeWindow) PropertyType.grid(column=1, row=addPropRow, sticky='we') ttk.Label(customAttributeWindow, text='Property Value:', justify='left').grid(column=0, row=addPropRow + 1, padx=5, pady=5, sticky='w') PropertyValue = Entry(customAttributeWindow) PropertyValue.grid(column=1, row=addPropRow + 1, sticky='we') AddPropButton = ttk.Button(customAttributeWindow, text='Add Property') AddPropButton.grid(row=addPropRow + 2, column=1, padx=5, pady=10, sticky='w') currentItem = self.tree.focus() AddPropButton['command'] = lambda: self.POMTreeView.addProperty( self.tree, currentItem, customAttributeWindow) def updateObjectProperty(self, actionType=None): currObj = self.POMTreeView.updateObjectProperty( self.tree, self.treeValues, self.currentItem) self.currentItem = currObj.ObjectID Util.focusTree(self.tree, currObj.ObjectID) self.displayObjectProperties()
class Interface: def __init__(self): log.info(f'{__name__} has been initialized.') self.window = Tk() self.window.title(f"FIB v{current_version}") self.window.geometry("380x225") self.style = Style() # if sys.platform == "win32": # self.style.theme_use('winnative') self.window.minsize(380, 200) self.window.wait_visibility(self.window) self.windowWidth = self.window.winfo_reqwidth() self.windowHeight = self.window.winfo_reqheight() # Gets both half the screen width/height and window width/height self.positionRight = int(self.window.winfo_screenwidth() / 2 - self.windowWidth / 2) self.positionDown = int(self.window.winfo_screenheight() / 2 - self.windowHeight / 2) self.window.geometry("+{}+{}".format(self.positionRight, self.positionDown)) self.window.grid_columnconfigure(0, weight=1) self.window.resizable(0, 0) self.window.attributes("-topmost", True) self.window.protocol("WM_DELETE_WINDOW", self.on_closing) self.main_menu = Menu(self.window) self.file_menu = Menu(self.main_menu, tearoff=0) # self.file_menu.add_command(label="Save") self.file_menu.add_command(label="Exit", command=self.menu_exit) self.help_menu = Menu(self.main_menu, tearoff=0) self.help_menu.add_command(label="About", command=self.menu_about) self.help_menu.add_command(label="Change License Key", command=self.menu_change_license) self.main_menu.add_cascade(label="File", menu=self.file_menu) self.main_menu.add_cascade(label="Help", menu=self.help_menu) self.window.config(menu=self.main_menu) self.info_label = Label(self.window, text="STOP BOT: SHIFT + ESC", font=("Helvetica", 16)) self.info_label.grid(column=0, row=0, padx=15, pady=10, columnspan=2) self.btn1 = Button(self.window, text="GENERAL OPTIONS", command=self.options_win, width=50) self.btn1.grid(column=0, row=1, padx=15, pady=5, columnspan=2) self.btn2 = Button(self.window, text="CONFIGURE PARTY", command=self.party_win, width=50) self.btn2.grid(column=0, row=2, padx=15, pady=0, columnspan=2) self.gobtn = Button(self.window, text="<--- START --->", command=self.ready_set_go, width=50) self.gobtn.config(foreground="white", background="blue") self.gobtn.grid(column=0, row=3, padx=15, pady=20, columnspan=2) # self.window.bind('<Control-n>', self.party_win) # self.window.after(300, self.status_win) self.window.mainloop() def ready_set_go(self): self.window.quit() self.window.withdraw() self.window.destroy() database.paused = False log.info(f"FIB v{current_version} was started!") def options_win(self, e=None): self.window.withdraw() self.options_win = Toplevel(self.window) self.options_win.protocol("WM_DELETE_WINDOW", self.options_on_close) self.options_win.title(f"FIB v{current_version}") # self.options_win.geometry("400x315") self.options_win.minsize(width=400, height=315) self.options_win.maxsize(width=400, height=315) self.options_win.grid_columnconfigure(0, weight=1) self.options_win.grid_columnconfigure(2, weight=1) self.options_win.resizable(width=False, height=False) # self.options_win.pack_propagate(0) self.options_win.attributes("-topmost", True) self.options_win.geometry("+{}+{}".format(self.positionRight, self.positionDown)) self.options_text = Label( self.options_win, text="Use the boxes below to set your preferred options.") self.options_text.grid(column=0, row=0, padx=15, pady=5, columnspan=2) # Toggle if you want the bot to automatically prestige for you self.prestige_state = BooleanVar(self.options_win) if database.auto_prestige: self.prestige_state.set(True) self.prestige_toggle = Checkbutton(self.options_win, text="Auto-Prestige?", var=self.prestige_state) self.prestige_toggle.grid(column=0, row=5, padx=15, pady=5, sticky="w") # Selection for update channel self.updates_label = Label(self.options_win, text="Updates Channel:") self.updates_label.grid(column=0, row=3, padx=15, pady=2, sticky="w") self.channel_choice = Combobox(self.options_win, state="readonly") self.channel_choice['values'] = ("Stable", "Development") if database.channel == "Stable": self.channel_choice.current(0) elif database.channel == "Development": self.channel_choice.current(1) else: self.channel_choice['values'] = self.channel_choice['values'] + ( database.channel, ) self.channel_choice.current(2) self.channel_choice.grid(column=0, row=4, padx=15, pady=5, sticky="w") self.guardian_label = Label(self.options_win, text="Which Guardian:") self.guardian_label.grid(column=0, row=1, padx=15, pady=2, sticky="w") self.guardian_choice = Combobox(self.options_win, state="readonly") self.guardian_choice['values'] = [x for x in database.guardians] if database.guardian == "Fairy": self.guardian_choice.current(1) elif database.guardian == "Dragon": self.guardian_choice.current(0) self.guardian_choice.grid(column=0, row=2, padx=15, pady=5, sticky="w") self.guild_missions_state = BooleanVar(self.options_win) if database.guild_missions: self.guild_missions_state.set(True) self.guild_missions_toggle = Checkbutton(self.options_win, text="Guild Missions?", var=self.guild_missions_state) self.guild_missions_toggle.grid(column=1, row=5, padx=15, pady=5, sticky="w") self.prestige_level_label = Label(self.options_win, text="Prestige Multiplier:") self.prestige_level_label.grid(column=1, row=1, padx=15, pady=2, sticky="w") self.prestige_level = Entry(self.options_win) self.prestige_level.grid(column=1, row=2, padx=15, pady=5, sticky="w") self.prestige_level.insert(0, database.prestige_level) self.g_btn = Button(self.options_win, text="SAVE", width=40, command=self.options_save) self.g_btn.grid(column=0, row=6, padx=15, pady=15, columnspan=2) self.g_btn.config(foreground="white", background="blue") def options_save(self, e=None): database.save_option('prestige_level', self.prestige_level.get()) # config['OPTIONS']['in_guild'] = str(self.guild_state.get()) database.save_option('auto_prestige', self.prestige_state.get()) database.save_option('guild_missions', self.guild_missions_state.get()) database.save_option('guardian', self.guardian_choice.get()) self.window.deiconify() self.options_win.destroy() def party_win(self, e=None): self.window.withdraw() self.party_win = Toplevel(self.window) self.party_win.protocol("WM_DELETE_WINDOW", self.party_on_close) self.party_win.title(f"FIB v{current_version}") # self.party_win.geometry("350x275") self.party_win.minsize(width=400, height=350) self.party_win.maxsize(width=400, height=350) self.party_win.resizable(width=False, height=False) self.party_win.grid_columnconfigure(0, weight=1) self.party_win.grid_columnconfigure(2, weight=1) self.party_win.attributes("-topmost", True) self.party_win.geometry("+{}+{}".format(self.positionRight, self.positionDown)) """ Begin building the GUI """ self.party_text = Label( self.party_win, text="Use the boxes below to set your party options.") self.party_text.grid(column=0, row=0, padx=15, pady=5, columnspan=2) self.party1_label = Label(self.party_win, text="Party Slot 01:") self.party1_label.grid(column=0, row=1, padx=15, pady=5, sticky="w") self.party2_label = Label(self.party_win, text="Party Slot 02:") self.party2_label.grid(column=1, row=1, padx=15, pady=5, sticky="w") self.party1 = Combobox(self.party_win, state="readonly") self.party1['values'] = [x for x in database.heroes] self.party1.current(4) self.party1.grid(column=0, row=2, padx=15, pady=5, sticky="w") self.party2 = Combobox(self.party_win, state="readonly") self.party2['values'] = [x for x in database.heroes] self.party2.current(10) self.party2.grid(column=1, row=2, padx=15, pady=5, sticky="w") self.party3_label = Label(self.party_win, text="Party Slot 03:") self.party3_label.grid(column=0, row=3, padx=15, pady=5, sticky="w") self.party4_label = Label(self.party_win, text="Party Slot 04:") self.party4_label.grid(column=1, row=3, padx=15, pady=5, sticky="w") self.party3 = Combobox(self.party_win, state="readonly") self.party3['values'] = [x for x in database.heroes] self.party3.current(5) self.party3.grid(column=0, row=4, padx=15, pady=5, sticky="w") self.party4 = Combobox(self.party_win, state="readonly") self.party4['values'] = [x for x in database.heroes] self.party4.current(2) self.party4.grid(column=1, row=4, padx=15, pady=5, sticky="w") self.party5_label = Label(self.party_win, text="Party Slot 05:") self.party5_label.grid(column=0, row=5, padx=15, pady=5, sticky="w") self.party_size_label = Label(self.party_win, text="Party Size:") self.party_size_label.grid(column=1, row=5, padx=15, pady=5, sticky="w") self.party5 = Combobox(self.party_win, state="readonly") self.party5['values'] = [x for x in database.heroes] self.party5.current(3) self.party5.grid(column=0, row=6, padx=15, pady=5, sticky="w") self.party_size = Combobox(self.party_win, state="readonly") self.party_size['values'] = ("1", "2", "3", "4", "5") self.party_size.current(4) self.party_size.grid(column=1, row=6, padx=15, pady=5, sticky="w") self.btn = Button(self.party_win, text="SAVE", command=self.party_save, width=40) self.btn.grid(column=0, row=7, padx=15, pady=15, columnspan=2) self.btn.config(foreground="white", background="blue") def party_save(self): heroes = database.heroes.copy() selections = [] selections.extend([ self.party2.get(), self.party3.get(), self.party4.get(), self.party5.get() ]) print(selections) party_slot_1 = self.party1.get() if party_slot_1 in heroes and party_slot_1 not in selections: database.save_option('party_slot_1', party_slot_1) heroes.remove(party_slot_1) else: messagebox.showerror( title="ERROR", message="PARTY SLOT 1: Invalid selection choice.") selections = [] selections.extend([ self.party1.get(), self.party3.get(), self.party4.get(), self.party5.get() ]) print(selections) party_slot_2 = self.party2.get() if party_slot_2 in heroes and party_slot_2 not in selections: database.save_option('party_slot_2', party_slot_2) heroes.remove(party_slot_2) else: messagebox.showerror( title="ERROR", message="PARTY SLOT 2: Invalid selection choice.") selections = [] selections.extend([ self.party1.get(), self.party2.get(), self.party4.get(), self.party5.get() ]) print(selections) party_slot_3 = self.party3.get() if party_slot_3 in heroes and party_slot_3 not in selections: database.save_option('party_slot_3', party_slot_3) heroes.remove(party_slot_3) else: messagebox.showerror( title="ERROR", message="PARTY SLOT 3: Invalid selection choice.") selections = [] selections.extend([ self.party1.get(), self.party2.get(), self.party3.get(), self.party5.get() ]) print(selections) party_slot_4 = self.party4.get() if party_slot_4 in heroes and party_slot_4 not in selections: database.save_option('party_slot_4', party_slot_4) heroes.remove(party_slot_4) else: messagebox.showerror( title="ERROR", message="PARTY SLOT 4: Invalid selection choice.") selections = [] selections.extend([ self.party1.get(), self.party2.get(), self.party3.get(), self.party4.get() ]) print(selections) party_slot_5 = self.party5.get() if party_slot_5 in heroes and party_slot_5 not in selections: database.save_option('party_slot_5', party_slot_5) heroes.remove(party_slot_5) else: messagebox.showerror( title="ERROR", message="PARTY SLOT 5: Invalid selection choice.") database.save_option('party_size', self.party_size.get()) self.window.deiconify() self.party_win.destroy() def status_win(self, e=None): # self.window.withdraw() print('Deploy status window') self.status_win = Toplevel(self.window) self.status_win.configure(background="black") self.status_win.overrideredirect(1) self.status_win.protocol("WM_DELETE_WINDOW", self.status_on_close) self.status_win.title(f"Idle Bot Status") self.status_win.geometry("350x35") self.status_win.grid_columnconfigure(0, weight=1) self.status_win.grid_columnconfigure(0, weight=2) self.status_win.resizable(0, 0) # self.status_win.pack_propagate(0) self.status_win.attributes("-topmost", True) self.status_win.geometry("+{}+{}".format(0, 0)) self.status_text = Label( self.status_win, foreground="white", background="black", text="IDLE BOT: Verify my settings before we get started.") self.status_text.grid(column=0, row=0, padx=5, pady=5, columnspan=2, sticky="w") def update_status(self, status): self.status_text.config(text=f"IDLE BOT: {status}") self.status_win.update() def menu_exit(self): self.window.quit() self.window.destroy() database.running = False def menu_change_license(self): self.change_license() def menu_about(self): if database.email: user = database.email else: user = "******" messagebox.showinfo( f"ABOUT", f"FIRESTONE IDLE BOT v{current_version}\n\nLICENSED TO: {user}\n{database.edition}\n\nThank you for supporting Firestone Idle Bot!", parent=self.window) def options_on_close(self): self.window.deiconify() self.options_win.destroy() def status_on_close(self): self.status_win.destroy() def party_on_close(self): self.window.deiconify() self.party_win.destroy() def on_closing(self): self.window.quit() self.window.destroy() database.running = False
class DateChooserPopup: def __init__(self, parent=None, firstweekday=6, startdate=None ): """ Args: parent (Widget): The parent widget; the popup is displayed to the bottom-right of the parent widget. startdate (datetime): The date to be in focus when the calendar is displayed. Current date is default. firstweekday (int): Specifies the first day of the week. ``0`` is Monday, ``6`` is Sunday (the default). **kw: """ self.parent = parent self.root = Toplevel() self.firstweekday = firstweekday self.startdate = startdate self.date_selected = startdate or datetime.today() self.date = startdate or self.date_selected self.calendar = calendar.Calendar(firstweekday=firstweekday) self.cframe = ttk.Frame(self.root, padding=0, borderwidth=1, relief='raised') self.xframe = ttk.Frame(self.cframe, style='primary.TFrame') self.tframe = ttk.Frame(self.cframe, style='primary.TFrame') self.wframe = ttk.Frame(self.cframe) self.dframe = None self.titlevar = StringVar(value=f'{self.date.strftime("%B %Y")}') self.datevar = IntVar() self.setup() self.root.grab_set() self.root.wait_window() def define_style(self): pass def draw_calendar(self): self.titlevar.set(f'{self.date.strftime("%B %Y")}') self.monthdays = self.calendar.monthdayscalendar(self.date.year, self.date.month) self.monthdates = self.calendar.monthdatescalendar(self.date.year, self.date.month) self.dframe = ttk.Frame(self.cframe) self.dframe.pack(fill='both', expand='yes') self.set_geometry() # calendar days for row, wk in enumerate(self.monthdays): for col, day in enumerate(wk): self.dframe.columnconfigure(col, weight=1) if day == 0: lbl = ttk.Label(self.dframe, text=self.monthdates[row][col].day, anchor='center') lbl.configure(style='secondary.TLabel', padding=(0, 0, 0, 10)) lbl.grid(row=row, column=col, sticky='nswe') else: if all([ day == self.date_selected.day, self.date.month == self.date_selected.month, self.date.year == self.date_selected.year ]): day_style = 'success.Toolbutton' else: day_style = 'calendar.primary.Outline.Toolbutton' rb = ttk.Radiobutton(self.dframe, variable=self.datevar, value=day, text=day, style=day_style) rb.configure(padding=(0, 0, 0, 10), command=lambda x=row, y=col: self.on_date_selected([x, y])) rb.grid(row=row, column=col, sticky='nswe') def draw_titlebar(self): """Create the title bar""" # previous month button self.btn_prev = ttk.Button(self.tframe, text='«', style='primary.TButton', command=self.on_prev_month) self.btn_prev.configure(style='chevron.primary.TButton') self.btn_prev.pack(side='left') # month and year title self.title_label = ttk.Label(self.tframe, textvariable=self.titlevar, anchor='center') self.title_label.configure(style='primary.Inverse.TLabel', font='helvetica 11') self.title_label.pack(side='left', fill='x', expand='yes') # next month button self.btn_next = ttk.Button(self.tframe, text='»', style='primary.TButton', command=self.on_next_month) self.btn_next.configure(style='chevron.primary.TButton') self.btn_next.pack(side='left') # days of the week header for wd in self.weekday_header(): wd_lbl = ttk.Label(self.wframe, text=wd, anchor='center', padding=(0, 5, 0, 10)) wd_lbl.configure(style='secondary.Inverse.TLabel') wd_lbl.pack(side='left', fill='x', expand='yes') def on_date_selected(self, index): row, col = index self.date_selected = self.monthdates[row][col] self.root.destroy() def on_next_month(self): year, month = calendar._nextmonth(self.date.year, self.date.month) self.date = datetime(year=year, month=month, day=1).date() self.dframe.destroy() self.draw_calendar() def on_prev_month(self): year, month = calendar._prevmonth(self.date.year, self.date.month) self.date = datetime(year=year, month=month, day=1).date() self.dframe.destroy() self.draw_calendar() def set_geometry(self): """Adjust the window size based on the number of weeks in the month""" w = 226 h = 255 if len(self.monthdates) == 5 else 285 # this needs to be adjusted if I change the font size. if self.parent: xpos = self.parent.winfo_rootx() + self.parent.winfo_width() ypos = self.parent.winfo_rooty() + self.parent.winfo_height() self.root.geometry(f'{w}x{h}+{xpos}+{ypos}') else: xpos = self.root.winfo_screenwidth()//2 - w ypos = self.root.winfo_screenheight() //2 - h self.root.geometry(f'{w}x{h}+{xpos}+{ypos}') def setup(self): """Setup the calendar widget""" self.cframe.pack(fill='both', expand='yes') self.xframe.pack(fill='x') self.tframe.pack(fill='x') self.wframe.pack(fill='x') # setup the top level window self.root.withdraw() # hide the window until setup is complete self.root.transient(self.parent) self.root.overrideredirect(True) self.root.resizable(False, False) self.cframe.update_idletasks() # actualize the geometry # create the visual components ttk.Button(self.xframe, text="⨉", command=self.root.destroy, style='exit.primary.TButton').pack(side='right') self.draw_titlebar() self.draw_calendar() self.root.deiconify() # make the window visible. self.root.attributes('-topmost', True) def weekday_header(self): """Returns a list of weekdays to be used as a header in the calendar based on the firstweekday""" weekdays = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'] return weekdays[self.firstweekday:] + weekdays[:self.firstweekday]
class Overlay(threading.Thread): def __init__(self, width, height, xpos, ypos, bgcolor, fgcolor, fontsize, opacity, messages, close): threading.Thread.__init__(self, daemon=True) self.width = width self.height = height self.xpos = xpos self.ypos = ypos self.bgcolor = bgcolor self.fgcolor = fgcolor self.fontsize = fontsize self.opacity = opacity self.messages = messages self.close = close username_colors = [ '#0000ff', '#ff7f50', '#1e90ff', '#00ff7f', '#9acd32', '#00ff00', '#ff4500', '#ff0000', '#daa520', '#ff69b4', '#5f9ea0', '#2e8b57', '#d2691e', '#8a2be2', '#b22222', ] self.color_for = defaultdict(lambda: random.choice(username_colors)) self.start() self.images = [] def die(self): self.images = None self.close.put('killme') self.root.quit() def run(self): self.root = MyRoot() self.root.lower() self.root.iconify() self.root.title('poetato overlay') self.root.protocol('WM_DELETE_WINDOW', self.die) self.app = Toplevel(self.root) self.app.geometry("%dx%d+%d+%d" % (self.width, self.height, self.xpos, self.ypos)) self.app.resizable(width=False, height=False) self.app.overrideredirect(1) self.app.minsize(width=self.width, height=self.height) self.app.maxsize(width=self.width, height=self.height) self.app.attributes( '-alpha', self.opacity, '-topmost', True, '-disabled', True, ) self.text = Text(self.app, bg=self.bgcolor, fg=self.fgcolor, wrap='word', state='disabled') self.text.configure(font=('Helvetica', self.fontsize, 'bold')) self.text.pack() self.app.lift() # tell Windows(tm) to allow clicks to pass through our overlay. hWindow = pywintypes.HANDLE(int(self.root.frame(), 16)) exStyle = (win32con.WS_EX_LAYERED | win32con.WS_EX_TRANSPARENT | win32con.WS_EX_NOACTIVATE) win32api.SetWindowLong(hWindow, win32con.GWL_EXSTYLE, exStyle) self.app.after(100, self.update) self.app.mainloop() def update(self): if self.messages.empty(): self.app.after(100, self.update) return msg = self.messages.get_nowait() self.text['state'] = 'normal' if self.text.index('end-1c') != '1.0': self.text.insert('end', '\n') self.text.insert('end', "{0}: ".format(msg.display_name)) emote_insertions = {} for eid, pos in msg.emotes.items(): for p in pos: emote_insertions[p[0]] = (msg.localemotes[eid], p[1]+1) cur_pos = 0 for i in sorted(emote_insertions.keys()): if cur_pos < i: self.text.insert('end', msg.message[cur_pos:i]) img = PhotoImage(file=emote_insertions[i][0]) self.text.image_create('end', image=img) # tkinter *needs* us to save a reference to a displayed image :( self.images.append(img) cur_pos = emote_insertions[i][1] if cur_pos < len(msg.message): self.text.insert('end', msg.message[cur_pos:]) color = self.color_for[msg.display_name] self.text.tag_config(msg.display_name, foreground=color, relief=RAISED) self.text.tag_add(msg.display_name, 'end-1l', 'end-1l wordend') self.text.see('end') self.text['state'] = 'disabled' self.app.after(100, self.update)
class About: def __init__(self): self.rootpath = '.\\' self.openAbout() def openAbout(self): self.about = Toplevel() w = 501 h = 240 ws = self.about.winfo_screenwidth() hs = self.about.winfo_screenheight() x = (ws / 2) - (w / 2) y = (hs / 2) - (h / 2) self.about.geometry('%dx%d+%d+%d' % (w, h, x, y)) self.about.resizable(0, 0) self.about.title('About Testcase Generator') self.about.attributes("-toolwindow", 1) self.about.protocol("WM_DELETE_WINDOW", self.closeAboutWindow) self.about.grab_set() self.about.iconbitmap(self.rootpath + 'appdata\\images\\favicon.ico') txt = Text(self.about, padx=10, pady=10, font=("Consolas", 10), wrap='word') self.hyperlink = HyperlinkManager.HyperlinkManager(txt) txt.tag_configure('bold', font='Consolas 11 bold') txt.tag_configure('header', font='Consolas 15 bold') txt.insert(INSERT, ' Testcase Generator\n', 'header') txt.insert(INSERT, ' version: 1.0.0\n') txt.insert(END, '\nTestcase Generator ', 'bold') txt.insert( END, "is a handy tool for preparing the input and output dataset for programming competition. " ) txt.insert(END, 'Input generator is implemented using ') txt.insert( END, 'CodeForces', self.hyperlink.add( partial(webbrowser.open, "https://www.codeforces.com/"))) txt.insert(END, ' testlib.h library in C++. ') txt.insert( END, "This tool is specially helpful for the problem author and tester of a programming competition." ) txt.insert(END, '\n\n') txt.insert( END, 'Github Repository', self.hyperlink.add( partial(webbrowser.open, "https://github.com/skmonir/testcase_generator/"))) txt.insert(END, '\n\n') txt.insert(END, 'Developed by ') txt.insert(END, 'Md Moniruzzaman', 'bold') txt.insert(END, ' <*****@*****.**>\n') txt.insert( END, 'Facebook', self.hyperlink.add( partial(webbrowser.open, "https://www.facebook.com/skmnrcse/"))) txt.insert(END, ' ') txt.insert( END, 'LinkedIn', self.hyperlink.add( partial(webbrowser.open, "https://www.linkedin.com/in/skmonir/"))) txt.insert(END, ' ') txt.insert( END, 'Github', self.hyperlink.add( partial(webbrowser.open, "https://www.github.com/skmonir/"))) txt.pack() txt.config(state=DISABLED) def closeAboutWindow(self): self.about.grab_release() self.about.destroy()
def __init__(self): super().__init__() self.title("Overlay") self.geometry("302x178+200+200") self.resizable(False, False) top = Toplevel() top.overrideredirect(True) top.attributes("-topmost", True) top.attributes("-transparentcolor", "SystemButtonFace") top.withdraw() def toggle(*args): if toggle_btn["text"] == "Start": toggle_btn["text"] = "Stop" top.deiconify() else: toggle_btn["text"] = "Start" top.withdraw() def move(): if top.state() == "normal": x, y = position() outline = int(self.outline_var.get() or 0) radius = int(self.radius_var.get() or 0) center = outline + radius width = height = center * 2 + 1 x -= center y -= center top.geometry(f"{width}x{height}+{x}+{y}") top.lift() self.after(10, move) cv = Canvas(top, highlightthickness=0) cv.bind("<Button-1>", toggle) cv.pack() def create_circle(x1, y1, x2, y2, **args): radius = (x2 - x1) // 2 center = (x2 + x1) // 2 cv.create_line( [ position for angle in range(361) for position in ( radius * sin(radians(angle)) + center, radius * cos(radians(angle)) + center ) ], fill=args["outline"], tags="shape", width=args["width"] ) shapes = { "circle": create_circle, "square": cv.create_rectangle } def changed(*args): outline = int(self.outline_var.get() or 0) // 2 center = outline * 2 + int(self.radius_var.get() or 0) cv.configure(width=center * 2 + 1, height=center * 2 + 1) cv.delete("shape") x1 = y1 = outline x2 = y2 = center * 2 - outline try: shapes[self.shape.get()]( x1, y1, x2, y2, outline=self.color_var.get(), width=outline * 2, tag="shape" ) except TclError: pass # Save this for future reference # def validate(action, index, value_if_allowed, prior_value, text, # validation_type, trigger_type, widget_name): # vcmd = ( # self.register(validate), # '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W' # ) # widget keyword arguments ( # validate="key", # validatecommand=vcmd # ) def validate(value_if_allowed, text): return value_if_allowed == "" or text in '0123456789' vcmd = (self.register(validate), '%P', '%S') self.radius_var = var("50", changed) label = ttk.Label(self, text="Radius:") label.grid(sticky="w", padx=5, pady=5) spin = ttk.Spinbox( self, from_=1, to_=float("inf"), textvariable=self.radius_var, validate="key", validatecommand=vcmd ) spin.grid(column=1, row=0, sticky="we", padx=5, pady=5) self.outline_var = var("5", changed) label = ttk.Label(self, text="Outline Width:") label.grid(column=0, row=1, sticky="w", padx=5, pady=5) spin = ttk.Spinbox( self, from_=1, to_=float("inf"), textvariable=self.outline_var, validate="key", validatecommand=vcmd ) spin.grid(column=1, row=1, sticky="we", padx=5, pady=5) self.color_var = var("blue", changed) label = ttk.Label(self, text="Color (name or hex value):") label.grid(column=0, row=2, sticky="w", padx=5, pady=5) entry = ttk.Entry(self, textvariable=self.color_var) entry.grid(column=1, row=2, sticky="we", padx=5, pady=5) frame = ttk.Frame(self) frame.grid(column=0, row=3, sticky="we", padx=5, pady=5) self.shape = var("circle", changed) ttk.Radiobutton( frame, text="Circle", variable=self.shape, value="circle" ).pack(anchor="w") ttk.Radiobutton( frame, text="Square", variable=self.shape, value="square" ).pack(anchor="w") toggle_btn = ttk.Button(self, text="Start", command=toggle) toggle_btn.grid(column=0, row=4, columnspan=2, padx=5, pady=5) changed() self.after(10, move) self.focus() self.mainloop()
def startPassGen(): global root root = Toplevel() root.attributes('-topmost', True) root.title(" Password Generator") root.geometry("350x380") # root.resizable(0,0) root.configure(bg="white") root.iconphoto(True, PhotoImage(file=assetpath + 'padlock.png')) root.tk.call('tk', 'scaling', 1.6) style = Style() style.configure("TLabel", background="white") style.configure('TCheckbutton', background='white') mainf = Frame(root, bg="white") mainf.pack(pady=20, padx=20, ipadx=10, ipady=10) f1 = Frame(mainf, bg="white") f1.pack() icon = ImageTk.PhotoImage( Image.open(assetpath + 'key.png').resize((45, 45))) Label(f1, image=icon, bg="white").grid(row=0, column=0, rowspan=2, padx=2, pady=5) Label(f1, text="Pass-Gen", font=('ARIAL', 15, 'bold'), bg="white").grid(row=0, column=2) Label(f1, text="Password Generator", bg="white").grid(row=1, column=2) f2 = Frame(mainf, bg="white") f2.pack(padx=10, pady=(30, 15)) global passe passe = Entry(f2, width=30) passe.pack(side=LEFT) copyi = ImageTk.PhotoImage( Image.open(assetpath + 'copy.png').resize((25, 25))) copyb = Button(f2, image=copyi, bg="white", bd=0, activebackground="white", command=lambda: copy2clip(passe.get())) copyb.pack(side=LEFT, padx=2) global length length = 8 lenf = Frame(mainf) lenf.pack() Label(lenf, text="Length ", bg="white").pack(side=LEFT) s = Spinbox(lenf, from_=4, to=25, width=5, command=lambda: setlength(s.get())) s.set(8) s.pack(side=LEFT) upper = BooleanVar() digit = BooleanVar() special = BooleanVar() upper.set(True) digit.set(True) special.set(True) f3 = Frame(mainf, bg="white") f3.pack(padx=10, pady=10) capb = Checkbutton(f3, text="Include Capitals", variable=upper, offvalue=False, onvalue=True) capb.pack(anchor=W, pady=5) digitb = Checkbutton(f3, text="Include Digits", variable=digit, offvalue=False, onvalue=True) digitb.pack(anchor=W, pady=5) specialb = Checkbutton(f3, text="Include Special Symbols", variable=special, offvalue=False, onvalue=True) specialb.pack(anchor=W, pady=5) genb = Button(mainf, text="Generate", command=lambda: passGen(length, upper.get(), digit.get(), special.get()), bg="turquoise3", activebackground="turquoise3", bd=0) genb.pack(pady=10, ipadx=20, padx=(43, 10), side=LEFT) exitb = Button(mainf, text="Exit", command=exitPassGen, bg="firebrick1", activebackground="firebrick1", bd=0, width=37) exitb.pack(pady=10, ipadx=20, padx=(10, 30), side=LEFT) root.mainloop()
class App(object): def __init__(self, bulk_processing=False, show_logging=True, gpu_id=None, instance_id=None, config_file=None, input_folder=None, file=None): self.root = Tk() self.bulk_processing = bulk_processing self.show_logging = show_logging self.cam = None self.cam_id = 0 self.input_source = None self.source_changed = False self.opencv_thread = None self.window = None self.tracker = None if self.bulk_processing: workspace.GlobalInit(['caffe2', '--caffe2_log_level=0']) self.input_source = file self.load_config_file(config_file) self.app_gpu = gpu_id self.app_save_det_result_path = input_folder self.app_save_tracking_result_path = input_folder self.setup_logging(__name__) self.logger = logging.getLogger(__name__) else: self.v_1: IntVar = IntVar() self.v_2: IntVar = IntVar() self.v_3: IntVar = IntVar() self.v_4: IntVar = IntVar() self.v_5: IntVar = IntVar() self.v_detector_to_use: StringVar = StringVar() self.v_tracker_to_use: StringVar = StringVar() self.v_detectron_model: StringVar = StringVar() self.v_chainer_model: StringVar = StringVar() self.chainercv_models = ['yolo_v2', 'yolo_v3', 'yolo_v2_tiny', 'ssd300', 'ssd512', 'fasterrcnnvgg16', 'fasterrcnnfpnresnet50', 'fasterrcnnfpnresnet101'] self.detectron_models = ['e2emaskrcnnR101FPN2x', 'e2efasterrcnnR101FPN2x', 'use config file settings'] self.trackers = ['deep_sort', 'sort'] self.detectors = ['detectron', 'chainer'] self.load_config_file('config.ini') self.logger = logging.getLogger(__name__) def run(self): self.main_window = main_window.MainWindow(self) self.root.mainloop() cv2.destroyAllWindows() sys.exit() def ask_for_options(self): self.config_window = config_window.ConfigWindow(self) def open_webcam(self): if self.cam_id is not None: self.input_source = self.cam_id self.source_changed = True self.start_video() def open_video(self): options = {} options['title'] = "Choose video" filename = askopenfilename(**options) if filename: self.input_source = filename self.source_changed = True self.start_video() def start_bulk(self): self.start_video() self.root.mainloop() sys.exit() def start_video(self): if self.opencv_thread is None: self.source_changed = False self.opencv_thread = Thread(target=self.run_opencv_thread) self.opencv_thread.daemon = True self.opencv_thread.start() if self.show_logging is True: self.show_logging_window() def run_opencv_thread(self): if self.app_display is True: cv2.namedWindow('source') self.start_processing() cv2.destroyAllWindows() self.opencv_thread = None def start_processing(self): if self.input_source is not None: file_stream = FileVideoStream(self.input_source, queue_size=self.app_imutils_queue_size).start() time.sleep(0.001) detector = self.initializeDetector() self.tracker = self.initializeTracker() self.setDataset() fps = FPS().start() frame_id = 0 all_boxes = {} tracking_boxes = [] while (not self.source_changed) and file_stream.running(): time.sleep(0.001) try: self.image = file_stream.read() if frame_id % self.app_process_every_nth_frame == 0: if(self.image is not None): vis = self.image.copy() cls_boxes = None cls_segms = None cls_keyps = None timers = defaultdict(Timer) t = time.time() fps.update() fps.stop() self.logger.info('Processing file {}'.format(self.input_source)) self.logger.info('Processing frame {}'.format(frame_id)) fps_text = "FPS " + "{:.2f}".format(fps.fps()) self.logger.info('FPS: ' + fps_text) if self.app_do_detection and not self.source_changed: cls_boxes, cls_segms, cls_keyps = self.infer(vis, timers, detector) all_boxes[frame_id] = cls_boxes self.logger.info('Inference time: {:.3f}s'.format(time.time() - t)) for k, v in timers.items(): self.logger.info(' | {}: {:.3f}s'.format(k, v.average_time)) if frame_id == 0: self.logger.info( ' \ Note: inference on the first image will be slower than the ' 'rest (caches and auto-tuning need to warm up)' ) fps_text = "FPS " + "{:.2f}".format(fps.fps()) self.logger.info('FPS: ' + fps_text) if self.app_display_det_result_img: if frame_id % self.app_display_det_every_nth_frame == 0 : vis = self.visualize_det(vis, cls_boxes, fps_text, segms=cls_segms, keypoints=cls_keyps) if self.app_save_det_result_img: if not self.app_display_det_result_img: ret = self.visualize_det(vis, cls_boxes, fps_text, segms=cls_segms, keypoints=cls_keyps) self.save_det_result_img(ret, frame_id) else: self.save_det_result_img(vis, frame_id) if self.app_do_tracking and not App.is_list_empty(cls_boxes) and not self.source_changed: t = time.time() tmp_tracking_boxes = self.track(self.image.copy(), cls_boxes, frame_id, timers) self.logger.info('Tracking time (incl. feature generation): {:.3f}s'.format(time.time() - t)) if self.app_display_tracking_result_img: if frame_id % self.app_display_tracking_every_nth_frame == 0 : vis = self.visualize_tracking(vis, tmp_tracking_boxes, fps_text) if self.app_save_tracking_result_img: if not self.app_display_tracking_result_img: ret = self.visualize_tracking(vis, tmp_tracking_boxes, fps_text) self.save_tracking_result_img(ret, frame_id) else: self.save_tracking_result_img(vis, frame_id) tracking_boxes = self.extend_result_boxes(frame_id, tracking_boxes, tmp_tracking_boxes) if self.app_display: cv2.imshow('source', vis) ch = 0xFF & cv2.waitKey(1) if ch == 27: break self.logger.info('Total time frame {}: {:.3f}s'.format(frame_id, time.time() - t)) frame_id += 1 except Exception: print(sys.exc_info()[0] + sys.exc_info()[1]) #continue if self.app_save_det_result_boxes: self.save_det_result_boxes(all_boxes) self.logger.info('Wrote detections to: {}'.format(os.path.abspath(self.app_save_det_result_path))) if self.app_save_tracking_result_boxes: self.save_tracking_result_boxes(list(tracking_boxes)) self.logger.info('Wrote tracks to: {}'.format(os.path.abspath(self.app_save_tracking_result_path))) file_stream.stop() self.source_changed = False if not self.bulk_processing: self.start_processing() else: self.root.quit() def initializeDetector(self): if self.app_detector_to_use == 'chainer': return detector_chainercv.Detector(self.app_gpu, self.chainer_model, self.chainer_ms_thresh, self.chainer_score_thresh) elif self.app_detector_to_use == 'detectron': cfg.immutable(False) if self.detectron_model == 'e2emaskrcnnR101FPN2x': detectron_cfg_tmp = 'Detectron/configs/12_2017_baselines/e2e_mask_rcnn_R-101-FPN_2x.yaml' detectron_wts_tmp = (str(self.detectron_download_cache) + '/35861858/12_2017_baselines/' 'e2e_mask_rcnn_R-101-FPN_2x.yaml.02_32_51.SgT4y1cO/output/train/' 'coco_2014_train:coco_2014_valminusminival/generalized_rcnn/model_final.pkl') elif self.detectron_model == 'e2efasterrcnnR101FPN2x': detectron_cfg_tmp = 'Detectron/configs/12_2017_baselines/e2e_faster_rcnn_R-101-FPN_2x.yaml' detectron_wts_tmp = (str(self.detectron_download_cache) + '/35857952/12_2017_baselines/' 'e2e_faster_rcnn_R-101-FPN_2x.yaml.01_39_49.JPwJDh92/output/train/' 'coco_2014_train:coco_2014_valminusminival/generalized_rcnn/model_final.pkl') else: detectron_cfg_tmp = self.detectron_cfg detectron_wts_tmp = self.detectron_wts merge_cfg_from_file(detectron_cfg_tmp) cfg.NUM_GPUS = 1 cfg.DOWNLOAD_CACHE = self.detectron_download_cache cfg.TEST.NMS = self.detectron_nms_thresh cfg.TEST.DETECTIONS_PER_IM = self.detectron_detections_per_im cfg.TEST.PROPOSAL_LIMIT = self.detectron_proposal_limit cfg.TEST.RPN_NMS_THRESH = self.detectron_rpn_nms_thresh cfg.TEST.SCORE_THRESH = self.detectron_score_thresh weights = cache_url(detectron_wts_tmp, cfg.DOWNLOAD_CACHE) assert_and_infer_cfg() _merge_a_into_b(cfg, infer_engine.cfg) return infer_engine.initialize_model_from_cfg(weights, self.app_gpu) def infer(self, image, timers, detector): cls_boxes = None cls_segms = None cls_keyps = None if self.app_detector_to_use == 'chainer': timers['chainer_detect'].tic() bboxes, labels, scores = detector.predict(image) timers['chainer_detect'].toc() cls_boxes = App.transform_to_detectron(bboxes, labels, scores) elif self.app_detector_to_use == 'detectron': with c2_utils.NamedCudaScope(self.app_gpu): cls_boxes, cls_segms, cls_keyps = infer_engine.im_detect_all( detector, image, None, timers=timers ) return cls_boxes, cls_segms, cls_keyps def visualize_det(self, vis, cls_boxes, fps_text, segms=None, keypoints=None): offsetX = 20 offsetY = 20 text_width = 100 text_height = 10 vis = detectron_visualizator.vis_one_image_opencv(vis, cls_boxes, segms=segms, keypoints=keypoints, thresh=self.app_vis_thresh, kp_thresh=self.detectron_kp_thresh, show_box=True, dataset=self.dataset, show_class=True) #(text_width, text_height) = cv2.getTextSize(fps_text, fontScale=cv2.FONT_HERSHEY_SIMPLEX, thickness=1) cv2.rectangle(vis, (offsetX - 2, offsetY - text_height - 2), (offsetX + 2 + text_width, offsetY + 2), (0, 0, 0), cv2.FILLED) cv2.putText(vis, fps_text, (offsetX, offsetY), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255)) return vis def save_det_result_img(self, vis, frame_id): try: head, tail = os.path.split(self.input_source) filename = os.path.splitext(tail)[0] cv2.imwrite(head + '/' + filename + '_' + str(frame_id) + '.png',vis) except Exception: e = sys.exc_info()[0] messagebox.showinfo("Error saving detection images", e) raise def save_det_result_boxes(self, all_boxes): try: target_lines = [] for frame_id, cls_boxes in all_boxes.items(): for cls_idx in range(1, len(cls_boxes)): dataset = self.dataset.classes for dets in cls_boxes[cls_idx]: line = [frame_id + 1, '-1', round(dets[0], 1), round(dets[1], 1), round(dets[2] - dets[0], 1), round(dets[3] - dets[1], 1), round(dets[4] * 100, 1), dataset[cls_idx], '-1', '-1', '-1'] target_lines.append(line) target_lines.sort(key=lambda x: x[0]) head, tail = os.path.split(self.input_source) filename = os.path.splitext(tail)[0] with open(head + '/' + filename + '_detections.csv', 'w+') as txtfile: wr = csv.writer(txtfile, lineterminator='\n') for val in target_lines: wr.writerow(val) except Exception: e = sys.exc_info()[0] messagebox.showinfo("Error saving detection images", e) raise def initializeTracker(self): if self.app_tracker_to_use == 'deep_sort': return tracker_deep_sort.DeepSortTracker(self.deep_sort_feature_model, self.deep_sort_max_cosine_distance, self.deep_sort_nn_budget, self.deep_sort_per_process_gpu_mem_fraction, self.app_gpu) elif self.app_tracker_to_use == 'sort': return tracker_sort.Sort() def track(self, vis, cls_boxes, frame_id, timers): result = None cls_boxes = [np.append(item, i) for i, sublist in enumerate(cls_boxes) for item in sublist] cls_boxes = np.asarray(cls_boxes) if self.app_tracker_to_use == 'deep_sort': timers['deep_sort'].tic() result = self.tracker.track(vis, cls_boxes, frame_id, self.deep_sort_min_detection_height, self.deep_sort_min_confidence, self.deep_sort_nms_max_overlap) timers['deep_sort'].toc() elif self.app_tracker_to_use == 'sort': timers['sort'].tic() cls_boxes[:,2:4] += cls_boxes[:,0:2] result = self.tracker.update(cls_boxes) timers['sort'].toc() return result def visualize_tracking(self, vis, tracking_boxes, fps_text): offsetX = 20 offsetY = 20 text_width = 100 text_height = 10 if self.app_tracker_to_use == 'deep_sort': vis = self.tracker.draw_trackers(vis, tracking_boxes, self.dataset.classes, self.deep_sort_min_confidence) if self.app_tracker_to_use == 'sort': vis = self.tracker.draw_trackers(vis, tracking_boxes) cv2.rectangle(vis, (offsetX - 2, offsetY - text_height - 2), (offsetX + 2 + text_width, offsetY + 2), (0, 0, 0), cv2.FILLED) cv2.putText(vis, fps_text, (offsetX, offsetY), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255)) return vis def save_tracking_result_img(self, vis, frame_id): try: cv2.imwrite(self.app_save_tracking_result_path + '/tracking_res_img_' + str(frame_id) + '.png',vis) head, tail = os.path.split(self.input_source) filename = os.path.splitext(tail)[0] cv2.imwrite(head + '/' + filename + '_tracking_' + str(frame_id) + '.png',vis) except Exception: e = sys.exc_info()[0] messagebox.showinfo("Error saving tracking images", e) raise def save_tracking_result_boxes(self, tracking_boxes): try: tracking_boxes.sort(key = lambda x: (x[0], x[1])) head, tail = os.path.split(self.input_source) filename = os.path.splitext(tail)[0] with open(head + '/' + filename + '_tracks.csv', 'w+') as txtfile: wr = csv.writer(txtfile, lineterminator='\n') for val in tracking_boxes: if self.app_tracker_to_use == 'deep_sort': val = [val[0] + 1, val[1], round(val[2], 2), round(val[3], 2), round(val[4], 2), round(val[5], 2), round(val[6], 1), -1, -1, -1] if self.app_tracker_to_use == 'sort': val = [val[0] + 1, int(val[5]), round(val[1], 1), round(val[2], 1), round(val[3], 1), round(val[4], 1)] wr.writerow(val) except Exception: e = sys.exc_info()[0] messagebox.showinfo("Error saving tracking boxes", e) raise def extend_result_boxes(self, frame_id, tracking_boxes, tmp_tracking_boxes): if self.app_tracker_to_use == 'deep_sort': conf_tracks = self.tracker.get_confirmed_tracks(frame_id) tracking_boxes.extend(conf_tracks) self.logger.info('Tracks in image: {} tracks'.format(len(conf_tracks))) elif self.app_tracker_to_use == 'sort': self.logger.info('Tracks in image: {} tracks'.format(len(tmp_tracking_boxes))) for index, obj in enumerate(tmp_tracking_boxes): tracking_boxes.extend([[frame_id, obj[0], obj[1], obj[2], obj[3], obj[4]]]) return tracking_boxes def setDataset(self): if self.app_detector_to_use == 'detectron': self.dataset = App.get_coco_dataset() elif self.app_detector_to_use == 'chainer' and ( self.chainer_model == 'fasterrcnnfpnresnet50' or self.chainer_model == 'fasterrcnnfpnresnet101'): self.dataset = App.get_coco_dataset(False) else: self.dataset = App.get_voc_dataset() def load_config_file(self, configfile=None): try: self.config = configparser.ConfigParser() self.config.sections() if configfile is None: options = {} options['title'] = "Choose config file" options['filetypes'] = [('Config file', '.ini')] options['defaultextension'] = "ini" filename = askopenfilename(**options) if filename: configfile = filename if configfile is not None: self.config.read(configfile) self.app_display = eval(self.config['App']['display']) self.app_gpu = int(self.config['App']['gpu']) self.app_save_det_result_img = eval(self.config['App']['save_det_result_img']) self.app_save_det_result_boxes = eval(self.config['App']['save_det_result_boxes']) self.app_save_det_result_path = self.config['App']['save_det_result_path'] self.app_save_tracking_result_img = eval(self.config['App']['save_tracking_result_img']) self.app_save_tracking_result_boxes = eval(self.config['App']['save_tracking_result_boxes']) self.app_save_tracking_result_path = self.config['App']['save_tracking_result_path'] self.app_display_det_result_img = eval(self.config['App']['display_det_result_img']) self.app_display_det_every_nth_frame = eval(self.config['App']['display_det_every_nth_frame']) self.app_process_every_nth_frame = eval(self.config['App']['process_every_nth_frame']) self.app_display_tracking_result_img = eval(self.config['App']['display_tracking_result_img']) self.app_display_tracking_every_nth_frame = eval(self.config['App']['display_tracking_every_nth_frame']) self.app_detector_to_use = self.config['App']['detector_to_use'] self.app_tracker_to_use = self.config['App']['tracker_to_use'] self.app_vis_thresh = float(self.config['App']['vis_thresh']) self.app_config_file = self.config['App']['config_file'] self.app_do_detection = eval(self.config['App']['do_detection']) self.app_do_tracking = eval(self.config['App']['do_tracking']) self.app_imutils_queue_size = int(self.config['App']['imutils_queue_size']) self.cam_id = int(self.config['App']['web_cam']) self.detectron_model = self.config['Detectron']['model'] self.detectron_cfg = self.config['Detectron']['cfg'] self.detectron_wts = self.config['Detectron']['wts'] self.detectron_kp_thresh = float(self.config['Detectron']['kp_thresh']) self.detectron_nms_thresh = float(self.config['Detectron']['nms_thresh']) self.detectron_download_cache = self.config['Detectron']['download_cache'] self.detectron_detections_per_im = int(self.config['Detectron']['detections_per_im']) self.detectron_proposal_limit = int(self.config['Detectron']['proposal_limit']) self.detectron_rpn_nms_thresh = float(self.config['Detectron']['rpn_nms_thresh']) self.detectron_score_thresh = float(self.config['Detectron']['score_thresh']) self.deep_sort_min_confidence = float(self.config['deep_sort']['min_confidence']) self.deep_sort_nn_budget = int(self.config['deep_sort']['nn_budget']) self.deep_sort_max_cosine_distance = float(self.config['deep_sort']['max_cosine_distance']) self.deep_sort_nms_max_overlap = float(self.config['deep_sort']['nms_max_overlap']) self.deep_sort_min_detection_height = int(self.config['deep_sort']['min_detection_height']) self.deep_sort_per_process_gpu_mem_fraction = float(self.config['deep_sort']['per_process_gpu_mem_fraction']) self.deep_sort_feature_model = self.config['deep_sort_features']['model'] self.chainer_model = self.config['chainer']['model'] self.chainer_ms_thresh = float(self.config['chainer']['ms_thresh']) self.chainer_score_thresh = float(self.config['chainer']['score_thresh']) if self.opencv_thread is not None: self.source_changed = True if not self.bulk_processing: self.update_main_gui() except Exception: e = sys.exc_info()[0] messagebox.showinfo("Error loading file", e) raise def save_config_file(self, configfile=None): try: self.config['App'] = {'display': self.app_display, 'gpu': self.app_gpu, 'save_det_result_img': self.app_save_det_result_img, 'save_det_result_boxes': self.app_save_det_result_boxes, 'save_det_result_path': self.app_save_det_result_path, 'save_tracking_result_img': self.app_save_tracking_result_img, 'save_tracking_result_boxes': self.app_save_tracking_result_boxes, 'save_tracking_result_path': self.app_save_tracking_result_path, 'display_det_result_img': self.app_display_det_result_img, 'display_det_every_nth_frame': self.app_display_det_every_nth_frame, 'display_tracking_result_img': self.app_display_tracking_result_img, 'display_tracking_every_nth_frame': self.app_display_tracking_every_nth_frame, 'detector_to_use': self.app_detector_to_use, 'tracker_to_use': self.app_tracker_to_use, 'vis_thresh': self.app_vis_thresh, 'config_file': self.app_config_file, 'process_every_nth_frame': self.app_process_every_nth_frame, 'do_detection': self.app_do_detection, 'do_tracking': self.app_do_tracking, 'imutils_queue_size': self.app_imutils_queue_size, 'web_cam': self.cam_id} self.config['Detectron'] = { 'model': self.detectron_model, 'cfg': self.detectron_cfg, 'wts': self.detectron_wts, 'kp_thresh': self.detectron_kp_thresh, 'nms_thresh': self.detectron_nms_thresh, 'download_cache': self.detectron_download_cache, 'detections_per_im': self.detectron_detections_per_im, 'proposal_limit': self.detectron_proposal_limit, 'rpn_nms_thresh': self.detectron_rpn_nms_thresh, 'score_thresh': self.detectron_score_thresh} self.config['deep_sort'] = {'min_confidence': self.deep_sort_min_confidence, 'nn_budget': self.deep_sort_nn_budget, 'max_cosine_distance': self.deep_sort_max_cosine_distance, 'nms_max_overlap': self.deep_sort_nms_max_overlap, 'min_detection_height': self.deep_sort_min_detection_height, 'per_process_gpu_mem_fraction': self.deep_sort_per_process_gpu_mem_fraction } self.config['deep_sort_features'] = {'model': self.deep_sort_feature_model} self.config['chainercv'] = {'model': self.chainer_model, 'ms_thresh': self.chainer_ms_thresh, 'score_thresh': self.chainer_score_thresh} options = {} options['filetypes'] = [('Config file', '.ini')] options['defaultextension'] = "ini" options['initialfile'] = "config.ini" options['title'] = "Where to save?" configfile = asksaveasfilename(**options) if configfile: with open(configfile, 'w') as configfile: self.config.write(configfile) except Exception: e = sys.exc_info()[0] messagebox.showinfo("Error saving file", e) raise def trans_img_chainer(img): buf = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) dst = np.asanyarray(buf, dtype=np.uint8).transpose(2, 0, 1) return dst def transform_to_detectron(bbox, label, score): #Detectron: all_boxes[cls][image] = N x 5 array with columns (x1, y1, x2, y2, score) label_names = voc_bbox_label_names cls_boxes = [[] for _ in range(len(label_names))] if label is not None and not len(bbox) == len(label): raise ValueError('The length of label must be same as that of bbox') if score is not None and not len(bbox) == len(score): raise ValueError('The length of score must be same as that of bbox') if label is not None: order = np.argsort(label) bbox = np.array(bbox[0]) score = np.array(score[0]) label = np.array(label[0]) bbox = bbox[order] score = score[order] label = label[order] if len(bbox) == 0: return tmp_label = None for i, bb in enumerate(bbox[0]): if tmp_label is None or tmp_label != label[0][i]: tmp_label = label[0][i] cls_boxes[tmp_label].append([bb[1], bb[0], bb[3], bb[2], score[0][i]]) return cls_boxes def get_coco_dataset(incl_background=True): ds = AttrDict() classes = [ '__background__', 'person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light', 'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush' ] if incl_background: ds.classes = {i: name for i, name in enumerate(classes)} else: ds.classes = {i: name for i, name in enumerate(classes[1:])} return ds def get_voc_dataset(): ds = AttrDict() classes = [ 'aeroplane', 'bicycle', 'bird', 'boat', 'bottle', 'bus', 'car', 'cat', 'chair', 'cow', 'diningtable', 'dog', 'horse', 'motorbike', 'person', 'pottedplant', 'sheep', 'sofa', 'train', 'tvmonitor' ] ds.classes = {i: name for i, name in enumerate(classes)} return ds def is_list_empty(inList): if isinstance(inList, list): return all( map(App.is_list_empty, inList) ) return False def on_closing(self): if messagebox.askokcancel("Quit", "Do you want to quit?"): if self.cam is not None: self.cam.release() sys.exit() def set_detector_to_use(self, event=None): if event is not None: self.app_detector_to_use = str(event.widget.get()) if self.opencv_thread is not None: self.source_changed = True def set_tracker_to_use(self, event=None): if event is not None: self.app_tracker_to_use = str(event.widget.get()) if self.opencv_thread is not None: self.source_changed = True def set_detectron_model(self, event=None): if event is not None: self.detectron_model = str(event.widget.get()) if self.opencv_thread is not None: self.source_changed = True def set_chainercv_model(self, event=None): if event is not None: self.chainer_model = str(event.widget.get()) if self.opencv_thread is not None: self.source_changed = True def set_display_det_result_img(self): self.app_display_det_result_img = bool(self.v_1.get()) def set_display_tracking_result_img(self): self.app_display_tracking_result_img = bool(self.v_4.get()) def set_do_tracking(self): self.app_do_tracking = bool(self.v_5.get()) def set_save_det_result_img(self): self.app_save_det_result_img = bool(self.v_2.get()) def set_save_tracking_result_img(self): self.app_save_tracking_result_img = bool(self.v_3.get()) def update_main_gui(self): self.v_1.set(self.app_display_det_result_img) self.v_2.set(self.app_save_det_result_img) self.v_4.set(self.app_display_tracking_result_img) self.v_3.set(self.app_save_tracking_result_img) self.v_5.set(self.app_do_tracking) self.v_detector_to_use.set(self.app_detector_to_use) self.v_tracker_to_use.set(self.app_tracker_to_use) self.v_detectron_model.set(self.detectron_model) self.v_chainer_model.set(self.chainer_model) self.root.update() def show_logging_window(self): if self.window is not None: self.window.destroy() if self.bulk_processing: self.window = self.root else: self.window = Toplevel(self.root) self.window.wm_title("Process/GPU: " + str(self.app_gpu)) self.window.resizable(width=True, height=True) self.window.attributes('-topmost', True) self.scrolled_text = tkst.ScrolledText(self.window, state='disabled', height=24) self.scrolled_text.grid(row=0, column=0, sticky=(N, S, W, E)) self.scrolled_text.configure(font='TkFixedFont') self.scrolled_text.tag_config('INFO', foreground='black') self.scrolled_text.tag_config('DEBUG', foreground='gray') self.scrolled_text.tag_config('WARNING', foreground='orange') self.scrolled_text.tag_config('ERROR', foreground='red') self.scrolled_text.tag_config('CRITICAL', foreground='red', underline=1) self.log_queue = queue.Queue() self.queue_handler = LoggingQueueHandler(self.log_queue) formatter = logging.Formatter('%(asctime)s: %(message)s') self.queue_handler.setFormatter(formatter) self.logger.addHandler(self.queue_handler) self.window.after(100, self.poll_log_queue) def display_logging(self, record): msg = self.queue_handler.format(record) self.scrolled_text.configure(state='normal') self.scrolled_text.insert(END, msg + '\n', record.levelname) self.scrolled_text.configure(state='disabled') self.scrolled_text.yview(END) def poll_log_queue(self): while True: try: record = self.log_queue.get(block=False) except queue.Empty: break else: self.display_logging(record) self.window.after(1000, self.poll_log_queue) def setup_logging(self, name): FORMAT = '%(levelname)s %(filename)s:%(lineno)4d: %(message)s' # Manually clear root loggers to prevent any module that may have called # logging.basicConfig() from blocking our logging setup logging.root.handlers = [] logging.basicConfig(level=logging.INFO, format=FORMAT, stream=sys.stdout) logger = logging.getLogger(name) return logger