def timed_messagebox(title, message): messagebox = Toplevel() messagebox.title(title) m = Message(messagebox, text=message, padx=100, pady=100) m.config(font=('TkDefaultFont', 20)) m.pack() messagebox.after(3000, messagebox.destroy)
def inventory(): inv_pop = Toplevel() inv_pop.geometry("400x300") inv_pop.title("Your Backpack") scroll = Scrollbar(inv_pop) scroll.pack(side=RIGHT, fill=Y) if not Player.inventory: Text_ = Text(inv_pop, bg="#837373", fg="#d9d9d9", yscrollcommand=scroll.set, relief="flat") Text_.insert(INSERT, "Nothing in here yet...") else: Text_ = Text(inv_pop, bg="#837373", fg="#d9d9d9", yscrollcommand=scroll.set, relief="flat") Text_.insert(INSERT, Player.get_inventory()) Text_.pack(expand=True) if OS == "Windows": Text_.config(font=("Times", 12)) scroll.config(command=Text_.yview) Text_.config(state=DISABLED) def update(): if Everything.inventory_uptodate is False: Text_.config(state=NORMAL) Text_.delete("1.0", END) if Player.get_inventory(): Text_.insert(INSERT, Player.get_inventory()) else: Text_.insert(INSERT, "Nothing in here yet...") Text_.config(state=DISABLED) Everything.inventory_uptodate = True Text_.see("end") inv_pop.after(500, update) inv_pop.after(1000, update)
def upload(): file_path_list = filedialog.askopenfilenames( initialdir="/", title='Upload single or multiple .pdf and/or .docx files') if len(file_path_list) != 0: window_width = 200 window_height = 100 screen_width = root.winfo_screenwidth() screen_height = root.winfo_screenheight() x = (screen_width / 2) - (window_width / 2) y = (screen_height / 2) - (window_height / 2) popup_loading = Toplevel() popup_loading.geometry( f'{window_width}x{window_height}+{int(x)}+{int(y)}') info = Label(popup_loading, text="Loading...") info.pack(fill='x', padx=15, pady=15) for file in file_path_list: name, extension = os.path.splitext(file) if extension == '.pdf': upload_pdf(file) elif extension == '.docx': upload_docx(file) else: upload_un_files(file) popup_loading.after(5000, lambda: popup_loading.destroy())
def showProcessInfoWindow(cls, destroyTime, title, message): infoWindow = Toplevel() infoWindow.title(title) infoWindow.geometry("%dx%d+%d+%d" % (300, 100, 100, 100)) Message(infoWindow, text=message, padx=20, pady=20, width=200).pack() infoWindow.after(destroyTime, infoWindow.destroy)
def show_tmp_message(message): ''' Displays a temporary message that is destroyed after 5 seconds ''' top = Toplevel() top.title('Welcome') Message(top, text=message, padx=20, pady=20).pack() top.after(5000, top.destroy)
def load_model_waiting_win(self, waiting_win: tk.Toplevel, load_thread: td.Thread): if load_thread.is_alive(): waiting_win.after( 100, lambda: self.load_model_waiting_win(waiting_win, load_thread)) else: waiting_win.pb.stop() waiting_win.destroy()
def rightCWindow(shit, editor, count=0): #---------search function------------- count = 0 framess = Toplevel() #framess = tkinter.Frame(popup) searchbox = tkinter.Entry(framess) searchbox.grid() #check = tkinter.Frame(popup) tkinter.intvar = count linelabel = tkinter.Label(framess, text='Navigate with index from index') linelabel.grid() nelabel = tkinter.Label(framess, text='Find Text') nelabel.grid() Cvalue = tkinter.Entry(framess) Cvalue.focus() Cvalue.grid() framess.after(500, lambda: framess.focus_force()) searchbox.after(700, lambda: searchbox.focus_force()) Cvalue.insert('end', str(count)) label = tkinter.Label(framess, text='jump to line') label.grid() thecount = lambda: navigation.count(Cvalue) butts2 = tkinter.Button(framess, foreground='blue', text='+', command=thecount) butts2.grid() tempfunc = lambda: controlers.searched( widget=searchbox, editor=editor, butts=Cvalue, linelabel=linelabel) butts = tkinter.Button(framess, foreground='blue', text='search', width=40, command=tempfunc) butts.grid() removeit = lambda: editor.tag_remove('highlight', '1.0', 'end') clearbutts = tkinter.Button(framess, width=40, foreground='blue', text='clear', command=removeit) clearbutts.grid()
def alertWindow(text="", fg="orange", font="Courier 14 bold"): wind = Toplevel(root) # new window wind.geometry("320x120") # set resolution wind.overrideredirect(1) # make window borderless # add text to window Label(wind, text=text, fg=fg, font=font, height=6, wraplength=300, justify=CENTER).place(x=160, y=60, anchor=CENTER) wind.after(3000, wind.destroy) # exit window after 3 seconds
def new_popup(self): pos = self._get_free_slot() if pos is None: return msg = self.communicator.get_message() new_window = Toplevel(self.parent) app = MessagePopup( parent=new_window, position=pos, color=msg.color, title=msg.title, text=msg.text, background=self._get_background(msg.color) ) self.slots[pos] = app new_window.after(self.popup_show_time, app.quit) new_window.after(self.popup_show_time + 500, lambda: self._clear_slot(pos)) self.update_counter_window()
class CreateToolTip(object): ''' create a tooltip for a given widget ''' def __init__(self, widget, text='widget info'): self.widget = widget self.text = text self.widget.bind("<Enter>", self.enter) self.widget.bind("<Leave>", self.close) self.ready = 0 def close(self, event=None): if hasattr(self, 'tw'): self.tw.destroy() self.ready = 0 else: self.ready = 0 def enter(self, event=None): def makeWidget(): self.tw = Toplevel(self.widget) def construct(): # Leaves only the label and removes the app window self.tw.wm_overrideredirect(True) # Places the tool-tip window close to the mouse pointer position x = y = 0 x, y, cx, cy = self.widget.bbox("insert") x += self.widget.winfo_rootx() + 25 y += self.widget.winfo_rooty() + 20 self.tw.wm_geometry("+%d+%d" % (x, y)) # changes the transparency of the tootip self.tw.wm_attributes("-alpha", 0.9) # puts a label inside the Toplevel widget self.label = tk.Label(self.tw, text=self.text, justify='left', background='white', relief='solid', borderwidth=1, font=("TkDefautlFont", "8", "normal")) self.label.pack(padx=0, pady=0) threading.Thread(target=self.tw.after(3000, construct())).start() def wait(delay): t = threading.Thread(target=time.sleep(delay)) t.start() self.ready = 1 #wait(3) makeWidget()
def character(): char_pop = Toplevel() char_pop.geometry("400x200") char_pop.title("You") if Player.ready is False: Text_ = Label(char_pop, anchor=W, justify="left", text="All so blurry...\n" "Who.. am I?...\n" "I need some water...") else: Text_ = Label(char_pop, anchor=W, justify="left", text=Player.pond()) Text_.grid(row=0, column=0) if OS == "Windows": Text_.config(font=("Times", 12)) def update(): if Player.ready is False: Text_.config(text="All so blurry...\nWho.. am I?...\nI need some water...") elif Everything.character_uptodate is False: Text_.config(text=Player.pond()) Everything.character_uptodate = True char_pop.after(500, update) char_pop.after(1000, update)
def nameHandler(name, message): '''Takes a string name and character, provides an interface for correcting the illegal name, returns a new legal string name.''' #todo: create a proper validate method def destroy(*args): root.destroy() root = Toplevel() root.title('Bad Name') root.resizable(False, False) root.after(100, root.focus_force) #todo: temp? mainFrame = ttk.Frame(root, padding=MAIN_PAD) mainFrame.grid(column=0, row=0, sticky='nwes') newname = StringVar(value=name) nameEntry = ttk.Entry(mainFrame, textvariable=newname) nameEntry.grid(row=1, sticky='we') ttk.Label(mainFrame, text=message).grid(row=0) for child in mainFrame.winfo_children(): child.grid(padx=5, pady=5) nameEntry.after(100, nameEntry.focus) #todo: temp? root.bind('<Return>', destroy) root.wait_window() #todo: disable the ability to close the window instead? add abort option? if len(newname.get()) < 1: return nameHandler(name, message) else: return newname.get()
def map_(): Map_pop = Toplevel() Map_pop.geometry("400x400") Map_pop.title("Your Map") Map_pop.config(bg="#CABB92") m = World.make_map() yscroll = Scrollbar(Map_pop) xscroll = Scrollbar(Map_pop, orient="horizontal") yscroll.pack(side=RIGHT, fill=Y) xscroll.pack(side=BOTTOM, fill=X) Text_ = Text(Map_pop, bg="#CABB92", fg="black", relief="flat", highlightbackground="#CABB92", font=("DejaVu Sans Mono", 14), yscrollcommand=yscroll.set, xscrollcommand=xscroll.set, wrap=NONE) Text_.insert("1.0", m) Text_.pack(expand=False) yscroll.config(command=Text_.yview) xscroll.config(command=Text_.xview) Text_.config(state=DISABLED) def update(): if Everything.map_uptodate is False: scrollposx = Text_.xview() scrollposy = Text_.yview() scrollposx = str(scrollposx)[1:-1].split(", ") scrollposy = str(scrollposy)[1:-1].split(", ") Text_.config(state=NORMAL) x = World.make_map() Text_.delete("1.0", END) Text_.insert("1.0", x) # the code below is for keeping the map # focus to where you scrolled it Text_.yview_moveto(float(scrollposy[0])) Text_.xview_moveto(float(scrollposx[0])) Text_.config(state=DISABLED) Everything.map_uptodate = True Map_pop.after(500, update) Map_pop.after(100, update)
class TakePicture: def __init__(self): """ Initialize application which uses OpenCV + Tkinter. It displays a video stream in a Tkinter window and stores current snapshot on disk """ print('Initializing TakePicture...') # capture video frames, 0 is your default video camera self.capture = cv2.VideoCapture(0) self.current_image = None # current image from the camera self.root = Toplevel() # initialize second window self.root.title("Photo Booth") # set window title # self.destructor function gets fired when the window is closed self.root.protocol('WM_DELETE_WINDOW', self.destructor) self.panel = ttk.Label(self.root) # initialize image panel self.panel.grid(column=0, row=0, columnspan=2, rowspan=1, padx=10, pady=10) # take picture button take_image_btn = ttk.Button(self.root, text="Cheese!", command=self.take_snapshot) take_image_btn.grid(column=0, row=2, pady=5) # exit / cancel cancel_btn = ttk.Button(self.root, text="Exit", command=self.destructor) cancel_btn.grid(column=1, row=2, pady=5) # start a self.video_loop that constantly pools the video sensor # for the most recently read frame self.video_loop() def video_loop(self): """ Get frame from the video stream and show it in Tkinter """ ret, frame = self.capture.read() # read frame from video stream if ret: # frame captured without any errors # convert colors from BGR to RGB cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) self.current_image = Image.fromarray( cv2image) # convert image for PIL # convert image for tkinter imgtk = ImageTk.PhotoImage(image=self.current_image) self.panel.imgtk = imgtk # anchor imgtk so it does not be deleted by garbage-collector self.panel.config(image=imgtk) # show the image # call the same function after 30 milliseconds self.root.after(30, self.video_loop) def take_snapshot(self): """ Take snapshot and save it to the file """ sleep(1) # add some effect to indicate that picture been taken pathlib.Path('images/').mkdir( exist_ok=True) # check if images dir exists, if not create image_name = 'face.jpg' # construct filename path_to_save = 'images/{}'.format(image_name) # where to save image self.current_image.save(path_to_save) # save image as jpeg file print("[INFO] saving image: {}".format(image_name)) def destructor(self): """ Destroy the second window object and release all resources """ print("[INFO] closing TakePicture...") self.root.destroy() self.capture.release() # release web camera cv2.destroyAllWindows() # it is not mandatory in this application
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 ImportFromDialog: def __init__(self, master, uf): self.master = master self.uf = uf self.top = Toplevel(self.master) self.top.title('Import keys from old device') self.top.geometry('+350+350') ImportFromDialog.path = '' # static member variable # default values for padding and sticky padyD = 5 padxD = 5 # Layout self.lblPW = Label(self.top, text='Enter passphrase to decrypte Files') self.lblPW.grid(row=0, columnspan=3, sticky=W, pady=padyD, padx=padxD) self.etyPw = Entry(self.top) self.etyPw.grid(row=1, columnspan=3, sticky=W+E, pady=padyD, padx=padxD) self.lblPath = Label(self.top, text='Import files from transport medium (e.g. USB-Stick):') self.lblPath.grid(row=2, columnspan=3, sticky=W+S, pady=padyD, padx=padxD) self.lblPathDisplay = Label(self.top, text=ImportFromDialog.path) self.lblPathDisplay.grid(row=3, columnspan=3, sticky=W+N, pady=padyD, padx=padxD) self.btnCancle = Button(self.top, text='Cancle', command=self.cancle, width=16) self.btnCancle.grid(row=4, sticky=W, pady=padyD, padx=padxD) self.btnPath = Button(self.top, text='Select path',command=self.change_path, width=16) self.btnPath.grid(row=4, column=1, sticky=W+E, pady=padyD, padx=padxD) self.btnOK = Button(self.top, text='OK',command=self.submit, width=16) self.btnOK.grid(row=4, column=2, sticky=E, pady=padyD, padx=padxD) self.update() # check display loop def update(self): self.lblPathDisplay.config(text=ImportFromDialog.path, font='Helvetica 8 bold') self.top.after(500, self.update) # call update() again after 500ms def change_path(self): ImportFromDialog.path = filedialog.askdirectory() self.top.lift(aboveThis=self.master) # lift the toplevel above master window again def cancle(self): self.top.destroy() def submit(self): pw = self.etyPw.get() # input check if len(pw) == 0: raise ExceptionMsg('No password provided', self.top, self.master) elif len(ImportFromDialog.path) == 0: raise ExceptionMsg('No path selected', self.top, self.master) else: try: # password verification happens as decryption with aes throws invalid tag exeption # if one of the elements (none, key, ...) is wrong. # if key is wrong its a password problem, thus catch the InvalidTag Exception self.uf.decrypt_private_keys(pw, ImportFromDialog.path) self.uf.import_other_files(ImportFromDialog.path) self.top.destroy() messagebox.showinfo('successfull', 'Data successfuly importetd') except FileNotFoundError as error: raise ExceptionMsg(error, self.top, self.master) except InvalidTag: raise ExceptionMsg('The password is wrong', self.top, self.master)
class ExportToDialog: def __init__(self, master, uf): self.master = master self.uf = uf self.top = Toplevel(self.master) self.top.title('Export keys for new device') self.top.geometry('+350+350') ExportToDialog.path = '' # static member variable, ramains on new button click as priviously selected # default values for padding and sticky padyD = 5 padxD = 5 # Layout self.lblPW = Label(self.top, text='Enter passphrase (Needed later on new device. Thus remember!') self.lblPW.grid(row=0, columnspan=3, sticky=W, pady=padyD, padx=padxD) self.etyPw = Entry(self.top) self.etyPw.grid(row=1, columnspan=3, sticky=W+E, pady=padyD, padx=padxD) self.lblPwCheck = Label(self.top, text='') self.lblPwCheck.grid(row=2, columnspan=3, sticky=W, pady=padyD, padx=padxD) self.lblPath = Label(self.top, text='Save Encrypted files to transport medium (e.g. USB-Stick):') self.lblPath.grid(row=3, columnspan=3, sticky=W+S, pady=padyD, padx=padxD) self.lblPathDisplay = Label(self.top, text=ExportToDialog.path) self.lblPathDisplay.grid(row=4, columnspan=3, sticky=W+N, pady=padyD, padx=padxD) self.btnCancle = Button(self.top, text='Cancle', command=self.cancle, width=16) self.btnCancle.grid(row=5, sticky=W, pady=padyD, padx=padxD) self.btnPath = Button(self.top, text='Select path',command=self.change_path, width=16) self.btnPath.grid(row=5, column=1, sticky=W+E, pady=padyD, padx=padxD) self.btnOK = Button(self.top, text='OK',command=self.submit, width=16) self.btnOK.grid(row=5, column=2, sticky=E, pady=padyD, padx=padxD) self.update() # check display loop def update(self): if len(self.etyPw.get()) > 0: # avoid errors when nothing entered yet text, color = self.uf.pw_checker(self.etyPw.get()) self.lblPwCheck.config(text=text, foreground = color) self.lblPathDisplay.config(text=ExportToDialog.path, font='Helvetica 8 bold') self.top.after(500, self.update) # call update() again after 500ms def change_path(self): ExportToDialog.path = filedialog.askdirectory() self.top.lift(aboveThis=self.master) # lift the toplevel above master window again def cancle(self): self.top.destroy() def submit(self): pw = self.etyPw.get() # input check if len(pw) == 0: raise ExceptionMsg('No password provided', self.top, self.master) elif len(ExportToDialog.path) == 0: raise ExceptionMsg('No path selected', self.top, self.master) else: try: self.uf.encrypt_private_keys(pw, ExportToDialog.path) self.uf.export_other_files(ExportToDialog.path) self.top.destroy() messagebox.showinfo('successfull', 'Data successfuly exportet to ' + self.path) except FileNotFoundError as error: raise ExceptionMsg(error, self.top, self.master)
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
class Flasher: def __init__(self): # create parent widget that'll live through the whole program self.root = Tk() self.root.withdraw() # menubar modification for macOS (to remove the default bloated Tkinter menu) menubar = Menu(self.root) appmenu = Menu(menubar, name='apple') menubar.add_cascade(menu=appmenu) appmenu.add_command(label='About VPFlasher') # inactive for now appmenu.add_separator() self.root['menu'] = menubar # initialized variables go here self.ring_has_timed_out = False self.call_status = "WAITING" self.ring_timeout = 0 self.session_timeout = 0 # bind callbacks to events self.root.bind("<<RingingOn>>", self.ringing_triggered) self.root.bind("<<RingingOff>>", self.ringing_terminated) self.root.bind("<<SessionOn>>", self.call_in_session) self.root.bind("<<SessionOff>>", self.session_terminated) # start "main program here" self.waiting_for_payload_in_thread() self.root.mainloop() ###### BEGINNING OF PAYLOAD PROCESSING ###### def connecting_payload(self): # return the readable string in a matched raw payload while True: # exit the program if main thread is terminated if not main_thread().is_alive(): sys.exit(1) # reset the payload processing if ringing timed out if self.call_status == "RINGING" and time() >= self.ring_timeout: self.ring_has_timed_out = True return frame = sniff( count=1, filter= '(tcp and dst port 5066) and (tcp[13] == 16 or tcp[13] == 24)', timeout=1) print("connecting_payload():", frame) # UNCOMMENT FOR DEBUG if len(frame) > 0: if frame[0].haslayer('Raw'): try: return frame[0].getlayer('Raw').load.decode("utf-8") except UnicodeDecodeError: return def has_session_keepalive_packet(self): # return the readable string in a matched raw payload sleep( 0.5 ) # reduce processing load on CPU due to excessive matched frames traversing frame = sniff(count=1, filter='udp and ip[2:2] = 200', timeout=1) if len(frame) > 0: print("Session keepalive found at", time()) # UNCOMMENT FOR DEBUG return True else: return False def payload_found(self, payload, *payload_search_string): # return True if all strings in parameter are found in the payload try: if all(substring in payload for substring in payload_search_string): return True except TypeError: # return False when the connection payload functions return NoneType return False def waiting_for_payload_in_thread(self): self.wait_thread = Thread(target=self.waiting_for_payload) self.wait_thread.start() def waiting_for_payload(self): self.call_status = "WAITING" while self.call_status == "WAITING": ### THIS IS THE ACTUAL START OF THE PROGRAM self.next_payload = self.connecting_payload() # set to 'RINGING' status if self.payload_found(self.next_payload, "SIP/2.0 180 Ringing"): print("It's ringing!") # UNCOMMENT FOR DEBUG self.call_status = "RINGING" self.ringing() def ringing(self): self.call_status = "RINGING" self.root.event_generate("<<RingingOn>>") self.ring_timeout = time() + 30 self.ring_has_timed_out = False while self.call_status == "RINGING": # collect potential next matched payload self.next_payload = self.connecting_payload() # branch out to 'connected' # 'CSeq: 2' = Convo, 'CSeq: 1' = Sorenson, and 'CSeq: 102' = Purple/ZVRS if (self.payload_found(self.next_payload, "SIP/2.0 200 OK", "CSeq: 2 INVITE") or self.payload_found(self.next_payload, "SIP/2.0 200 OK", "CSeq: 1 INVITE") or self.payload_found(self.next_payload, "SIP/2.0 200 OK", "CSeq: 102 INVITE")): print("You're now connected!") # UNCOMMENT FOR DEBUG self.root.event_generate("<<RingingOff>>") self.in_call() break # branch out to 'cancelled'. This applies to calls not being timely answered too. # 'CSeq: 2' = Convo, 'CSeq: 1' = Sorenson, and 'CSeq: 102' = Purple/ZVRS elif (self.payload_found(self.next_payload, "SIP/2.0 200 OK", "CSeq: 2 CANCEL") or self.payload_found(self.next_payload, "SIP/2.0 200 OK", "CSeq: 1 CANCEL") or self.payload_found( self.next_payload, "SIP/2.0 200 OK", "CSeq: 102 CANCEL")) or self.ring_has_timed_out: print("The call has been cancelled before you can answer." ) # UNCOMMENT FOR DEBUG self.call_status = "WAITING" self.root.event_generate("<<RingingOff>>") break # branch out to 'busy' elif self.payload_found(self.next_payload, "SIP/2.0 486 Busy Here"): print("Okay! We see you're busy. :) ") # UNCOMMENT FOR DEBUG self.call_status = "WAITING" self.root.event_generate("<<RingingOff>>") break elif self.payload_found(self.connecting_payload(), "SIP/2.0 180 Ringing"): # ring for new inbound call in case of network disconnection and reconnection while ringing self.root.event_generate("<<RingingOff>>") self.ringing() def in_call(self): # process "keep-alive" payload in while loop. If not, call session has timed out self.call_status = "IN_CALL" self.root.event_generate("<<SessionOn>>") print("Call session has begun at", time()) # UNCOMMENT FOR DEBUG self.session_timeout = time() + 1 while self.call_status == "IN_CALL": # just process the sniff() function in connected_payload() as it appears an UDP packet # with IP header total length of exactly 200 bytes may be very unique to RTP traffic # exit the program if main thread is terminated if not main_thread().is_alive(): sys.exit(1) # resume to listen for new incoming call if session terminated if time() >= self.session_timeout: print("Call session has timed out at ", time()) # UNCOMMENT FOR DEBUG self.call_status = "WAITING" # extend timeout value as long as there exists a keepalive packet if self.has_session_keepalive_packet(): self.session_timeout = time() + 1 self.root.event_generate("<<SessionOff>>") ###### END OF PAYLOAD PROCESSING ###### # ###### BEGINNING OF GUI BUILDING ###### def create_flasher_ui(self): self.flash_widget = Toplevel(master=self.root) self.flash_widget.title("") self.flash_widget_width = self.flash_widget.winfo_screenwidth() self.flash_widget_height = self.flash_widget.winfo_screenheight() self.flash_widget.wm_resizable(width=False, height=False) # self.flash_widget.configure(background='#76B53E') # green flashing widget self.flash_widget.configure(background='Blue') # blue flashing widget self.flash_widget.attributes('-alpha', 0.7) self.flash_widget.geometry("0x0+0+0") self.flash_widget.protocol("WM_DELETE_WINDOW", self.terminate_program) def flashing_widget(self): self.flash_widget.after( 100, self.flash_widget.geometry, "{0}x{1}+0+0".format(self.flash_widget_width, self.flash_widget_height)) self.flash_widget.after(200, self.flash_widget.geometry, "0x0+0+0") self.flash_widget.after(300, self.flashing_widget) def create_in_call_ui(self): self.in_call_widget = Toplevel(master=self.root) self.in_call_widget.title("CALL IN SESSION") self.in_call_widget.attributes('-alpha', 0.8) self.in_call_widget_width = int( self.in_call_widget.winfo_screenwidth() / 4.5) self.in_call_widget_height = int( self.in_call_widget.winfo_screenheight() / 4) self.in_call_widget.geometry("{0}x{1}+0+0".format( self.in_call_widget_width, self.in_call_widget_height)) self.in_call_widget.wm_resizable(width=False, height=False) self.in_call_widget.protocol("WM_DELETE_WINDOW", self.terminate_program) # create a label inside the widget self.in_call_text = Label(self.in_call_widget, text="CALL IN SESSION") self.in_call_text.configure( font=("TkDefaultFont", 20, "bold"), foreground="white", background="red", ) self.in_call_text.pack(fill=BOTH, expand=1) ###### END OF GUI BUILDING ###### # ###### BEGINNING OF EVENT BINDING ###### def ringing_triggered(self, event): self.create_flasher_ui() self.flashing_widget() def ringing_terminated(self, event): self.flash_widget.destroy() def call_in_session(self, event): self.create_in_call_ui() def session_terminated(self, event): self.in_call_widget.destroy() ###### END OF EVENT BINDING ###### # ###### BEGINNING OF MISCELLANEOUS FUNCTIONS ###### def terminate_program(self): sys.exit(1)
class GUI(object): def __init__(self): self.root = tkinter.Tk() self.root.title("区块链价格预测系统") self.root.geometry('370x370') self.dataGet_button = tkinter.Button(self.root, command=self.dataGet, text='最新数据', width=25, height=3) self.dataAnalysis_button = tkinter.Button(self.root, command=self.dataAnalysis, text='分析数据', width=25, height=3) self.PricePredict_button = tkinter.Button(self.root, command=self.Predict, text='价格预测', width=25, height=3) def GuiArrang(self): self.dataGet_button.place(x=100, y=50) self.dataAnalysis_button.place(x=100, y=120) self.PricePredict_button.place(x=100, y=190) def dataGet(self): self.top = Toplevel() self.top.title = ('数据获取') self.top.geometry('600x700') tmp = None def arrang(): currency1Chosen.place(x=60, y=20) currency1Chosen.current(0) currency2Chosen.place(x=280, y=20) currency2Chosen.current(0) label_to.place(x=220, y=20) Submit_button.place(x=400, y=20) Drawing_button.place(x=500, y=20) self.tree.column("a", width=125, anchor="center") self.tree.column("b", width=100, anchor="center") self.tree.column("c", width=100, anchor="center") self.tree.column("d", width=100, anchor="center") self.tree.column("e", width=100, anchor="center") self.tree.heading("a", text="订单时间") self.tree.heading("b", text="买卖类型") self.tree.heading("c", text="币种单价") self.tree.heading("d", text="成交币种数量") self.tree.heading("e", text="订单总额") self.tree.place(x=38, y=80) vbar.place(x=695, y=30, height=550) def dataCrawl(): rootUrl = 'https://data.gateio.co/api2/1/tradeHistory/' currency1.get() url = rootUrl + currency1.get() + '_' + currency2.get() browsers = requests.get(url).json() items = None if (browsers["result"] == "true"): items = browsers["data"] else: messagebox.showinfo(title='error', message='Please Retry') for _ in map(self.tree.delete, self.tree.get_children("")): pass for item in items: self.tree.insert("", "end", values=(item["date"], item["type"], item["rate"], item["amount"], item["total"])) Drawing_button['state'] = 'active' def dataDrawing(): messagebox.showinfo(title='Waiting~', message='I am drawing!') currency1 = tkinter.StringVar() currency2 = tkinter.StringVar() currency1Chosen = ttk.Combobox(self.top, width=12, textvariable=currency1) currency1Chosen['values'] = ('eth', 'btc') label_to = tkinter.Label(self.top, text='to') currency2Chosen = ttk.Combobox(self.top, width=12, textvariable=currency2) currency2Chosen['values'] = ('usdt', 'cnyx') Submit_button = tkinter.Button(self.top, command=dataCrawl, text='开始抓取') Drawing_button = tkinter.Button(self.top, command=dataDrawing, text='绘制图表', state='disabled') self.tree = ttk.Treeview(self.top, show="headings", height=28, columns=("a", "b", "c", "d", "e")) vbar = ttk.Scrollbar(self.tree, orient='vertical', command=self.tree.yview) self.tree.configure(yscrollcommand=vbar.set) arrang() def Predict(self): self.top = Toplevel() self.top.title = ('数据获取') self.top.geometry('600x400') ave_price_show = tkinter.StringVar() origin_price_data_show = tkinter.StringVar() predicted_price_show = tkinter.StringVar() self.i = 0 def price_predict(): url = 'https://data.gateio.co/api2/1/tradeHistory/btc_usdt' data = [] load_btc_data(url, data) data_process(data) origin_price_data = copy.deepcopy(np.array(data).T[1]) # 对数据归一化 new_btc_data, max, min = data_nornalization(data) new_btc_data = np.array(new_btc_data).reshape((1, 80, 4)) ave_price = origin_price_data.mean() # 预测价格 result = predict(new_btc_data) predicted_price = result[0][0] * (max[1] - min[1]) + min[1] ave_price_show.set('最新80笔交易的平均价格:' + str(ave_price)) origin_price_data_show.set('当前最新价格:' + str(origin_price_data[-1])) predicted_price_show.set('预测的下一次交易的价格:' + str(predicted_price)) print('最新80笔交易的平均价格:{}'.format(ave_price)) print('当前最新价格:{}'.format(origin_price_data[-1])) print('预测的下一次交易的价格:{}'.format(predicted_price)) # 可视化 l1 = range(1, len(origin_price_data) + 1) plt.figure() plt.plot(l1, origin_price_data, 'b-', color='blue') l2 = [80, 81] predict_data = [origin_price_data[-1], predicted_price] plt.plot(l2, predict_data, 'b-o', color='red') image_name = 'predict\predicted_price' + str(self.i) + '.png' self.i += 1 plt.savefig(image_name) image = self.Png_To_Gif(image_name) self.imgLabel.config(image=image) self.imgLabel.image = image self.top.update_idletasks() self.top.after(100) B = tkinter.Button(self.top, text='预测下一次交易的价格', command=price_predict) B.pack() l_ave_price = tkinter.Label(self.top, textvariable=ave_price_show) l_origin_price_data = tkinter.Label( self.top, textvariable=origin_price_data_show) l_predicted_price = tkinter.Label(self.top, textvariable=predicted_price_show) self.imgLabel = tkinter.Label(self.top) l_ave_price.pack() l_origin_price_data.pack() l_predicted_price.pack() self.imgLabel.pack() def Png_To_Gif(self, image_name): image = Image.open(image_name) (x, y) = image.size x_s = int(x / 2) y_s = int(y / 2) image = image.resize((x_s, y_s), Image.ANTIALIAS) image = ImageTk.PhotoImage(image) return image def dataAnalysis(self): self.top = Toplevel() self.top.title = ('数据分析') self.top.geometry('700x700') canvas = tkinter.Canvas(self.top, width=800, height=800, scrollregion=(0, 0, 1400, 1400)) # 创建canvas canvas.place(x=0, y=0) # 放置canvas的位置 frame = tkinter.Frame(canvas, width=1400, height=1400) # 把frame放在canvas里 frame.place(x=0, y=0) # frame的长宽,和canvas差不多的 vbar = tkinter.Scrollbar(canvas, orient='vertical') # 竖直滚动条 vbar.place(x=680, width=20, height=700) vbar.configure(command=canvas.yview) canvas.config(yscrollcommand=vbar.set) # 设置 image1 = self.Png_To_Gif('data_analyse\\all_trade_all.png') image2 = self.Png_To_Gif('data_analyse\\all_trade_big_volume.png') image3 = self.Png_To_Gif('data_analyse\\buy_all.png') image4 = self.Png_To_Gif('data_analyse\\buy_big_colume.png') image5 = self.Png_To_Gif('data_analyse\\sell_all.png') image6 = self.Png_To_Gif('data_analyse\\sell_big_volume.png') image7 = self.Png_To_Gif('data_analyse\\list1.png') image8 = self.Png_To_Gif('data_analyse\\list2.png') self.img_label1 = tkinter.Label(frame, image=image1) self.img_label2 = tkinter.Label(frame, image=image2) self.img_label3 = tkinter.Label(frame, image=image3) self.img_label4 = tkinter.Label(frame, image=image4) self.img_label5 = tkinter.Label(frame, image=image5) self.img_label6 = tkinter.Label(frame, image=image6) self.img_label7 = tkinter.Label(frame, image=image7) self.img_label8 = tkinter.Label(frame, image=image8) self.img_label1.image = image1 self.img_label2.image = image2 self.img_label3.image = image3 self.img_label4.image = image4 self.img_label5.image = image5 self.img_label6.image = image6 self.img_label7.image = image7 self.img_label8.image = image8 self.img_label1.place(x=0, y=0) self.img_label2.place(x=350, y=0) self.img_label3.place(x=0, y=250) self.img_label4.place(x=350, y=250) self.img_label5.place(x=0, y=500) self.img_label6.place(x=350, y=500) self.img_label7.place(x=0, y=750) self.img_label8.place(x=0, y=860) text = '从上面的六个图和两个价格差的对比表格可以明显看出:\n' \ '在所有交易中,所有交易平均的价格差方差为75.5788,而大额交易的价格差方差为78.9996,由此可以看出大额交易使得价格的变化波动加剧,但总体来说对价格的变化并不是很明显,交易后比交易前价格平均上升0.20左右。但对买入和卖出的交易分别分析。可以发现,大额交易对价格有非常明显的影响。\n' \ '在买入交易中,平均的价格差方差为151.0677而大额交易前后的价格差方差达到了163.9778。可见在买入交易中,大额交易前后价格的波动加剧。而在价格差平均值方面,所有买入的交易前后价格差基本没变化,而在大额交易后,价格上升了0.31。由此可以发现:\n' \ '大额买入显著提升了比特币的价格。\n' \ '在卖出交易中,平均的价格差方差为155.8411而大额交易前后的价格差方差达到了166.9491。可见在卖出交易中,大额交易前后价格的波动加剧。而在价格差平均值方面,两者的价格差也基本持平。\n' \ '最终我们得出结论: 大额交易使得交易价格的波动加剧,而大额交易对价格的影响主要体现在买入交易中,大额买入显著提升了比特币的价格。\n' label1 = tkinter.Label(frame, text=text, width=800, height=30, wraplength=600, justify='left', anchor='nw') label1.place(x=0, y=980) canvas.create_window((700, 700), window=frame)
def report_webcam_csv(csv_name, confidence, model_checkpoint='models', classifier='models/your_model.pkl', video_file=None, output_file=None): start_1 = time.time() global lst_student lst_student = [] time_per_student = [] # Set fps frame_interval = 3 # Number of frames after which to run face detection fps_display_interval = 5 # seconds frame_rate = 0 frame_count = 0 if video_file is not None: video_capture = cv2.VideoCapture(video_file) else: # Use internal camera video_capture = cv2.VideoCapture(0) ret, frame = video_capture.read() width = frame.shape[1] height = frame.shape[0] if output_file is not None: video_format = cv2.VideoWriter_fourcc(*'XVID') out = cv2.VideoWriter(output_file, video_format, 20, (width, height)) face_recognition = Recognition(model_checkpoint, classifier) start_time = time.time() colors = np.random.uniform(0, 255, size=(1, 3)) while True: # Capture frame-by-frame ret, frame = video_capture.read() image_1 = create_blank_image(500, height) if (frame_count % frame_interval) == 0: faces = face_recognition.identify(frame) for i in range(len(colors), len(faces)): colors = np.append(colors, np.random.uniform(150, 255, size=(1, 3)), axis=0) # Check our current fps end_time = time.time() if (end_time - start_time) > fps_display_interval: frame_rate = int(frame_count / (end_time - start_time)) start_time = time.time() frame_count = 0 add_overlays_webcam_report(frame, faces, frame_rate, colors, confidence=confidence) frame_count += 1 # Want to save? if len(faces) == 1: if faces[0].prob > confidence: if faces[0].name not in lst_student: start_rp = time.time() top_resp = Toplevel() top_resp.after(3000, top_resp.destroy) #print(faces[0].name) #print(type(faces[0].name)): string #response = messagebox.askyesno("Face detected", faces[0].name + "\n" + "Want to save?") response = messagebox.askyesno("Face detected", faces[0].name, parent=top_resp, default="yes") if response: top_resp.destroy() lst_student.append(faces[0].name) add_to_csv(faces[0].name, csv_name) end_rp = time.time() print("Time per student:", end_rp - start_rp) time_per_student.append(end_rp - start_rp) if len(lst_student) >= 1: if len(lst_student) > 5: add_to_blank_frame(image_1, list(enumerate(lst_student, start=1))[-5:]) else: add_to_blank_frame(image_1, list(enumerate(lst_student, start=1))) if video_file is not None: frame75 = rescale_frame(frame, percent=75) cv2.imshow('Video', frame75) else: final = cv2.hconcat([frame, image_1]) #cv2.imshow('Video', frame) cv2.imshow('Video', final) if output_file is not None: out.write(frame) if cv2.waitKey(1) & 0xFF == ord('q'): break # When everything is done, release the capture if output_file is not None: out.release() video_capture.release() cv2.destroyAllWindows() end_1 = time.time() print("Time per student:", time_per_student) print('Total Execute time:', end_1 - start_1)
class MainWindow: def __init__(self, rally_configuration, server_conn, running_as_exe): self.running_as_exe = running_as_exe self.subprocess_communicator = SubProcessCommunicator(server_conn) self.subprocess_communicator.start() self.server_connection = server_conn # server_conn.report_lost_connection = self.on_lost_connection # server_conn.message_receiver = self.on_message_received self.rally_configuration = rally_configuration self.sub_processes = SubProcesses(self.subprocess_communicator, self.rally_configuration, self.running_as_exe, self.server_connection.temporary_config_file) self.positions_map = {"Utanför bussen": 0, "Förare": 1, "Kartläsare": 2, "Fram höger": 3, "Mitten vänster": 4, "Protokollförare": 5, "Mitten höger": 6, "Bak vänster": 7, "Bak mitten": 8, "Bak höger": 9} self.all_positions = ["Utanför bussen", "Förare", "Kartläsare", "Fram höger", "Mitten vänster", "Protokollförare", "Mitten höger", "Bak vänster", "Bak mitten", "Bak höger"] self.main_window = None self.combo_select_seating = None self.placing_label = None self.placing_button = None self.rebus_button = None self.seats = [] self.messages_text = None self.minibus_img = None self.layout() self.server_connection.start_client_loop(self.on_lost_connection, self.on_message_received, self.subprocess_communicator) def run(self): self.main_window.mainloop() if self.main_window is not None: self.main_window.destroy() def layout(self): self.main_window = Toplevel() #self.main_window.withdraw() self.main_window.title(self.rally_configuration.title) self.minibus_img = ImageTk.PhotoImage(Image.open("minibus.png")) w2 = self.minibus_img.width() h2 = self.minibus_img.height() f_bus = Frame(self.main_window, width=w2, height=480) background_label2 = Label(f_bus, image=self.minibus_img) # background_label2.place(x=0, y=0, relwidth=1, relheight=1) background_label2.grid(row=0, column=0, sticky=N) f_bus.grid(row=0, column=0, sticky=N) f_placing = Frame(f_bus) self.placing_label = Label(f_placing, text="Välj plats i bussen:") self.placing_label.grid(row=0, column=0) self.combo_select_seating = Combobox(f_placing, values=self.all_positions) self.combo_select_seating.current(0) self.combo_select_seating.grid(row=1, column=0) self.combo_select_seating.bind("<<ComboboxSelected>>", self.on_placing_cb_changed) f_placing.grid(row=1, column=0, sticky=N) self.placing_button = Button(f_placing, command=self.on_select_placing, text="Aktivera vald plats i bussen") self.placing_button.grid(row=2, column=0) self.rebus_button = Button(f_placing, command=self.on_search_for_rebus, text="Leta efter rebuskontroll här") self.rebus_button.grid(row=3, column=0) seat1 = Label(background_label2, text="") seat1.place(x=35, y=130) seat2 = Label(background_label2, text="") seat2.place(x=75, y=150) seat3 = Label(background_label2, text="") seat3.place(x=110, y=170) seat4 = Label(background_label2, text="") seat4.place(x=35, y=195) seat5 = Label(background_label2, text="") seat5.place(x=75, y=215) seat6 = Label(background_label2, text="") seat6.place(x=110, y=235) seat7 = Label(background_label2, text="") seat7.place(x=35, y=270) seat8 = Label(background_label2, text="") seat8.place(x=75, y=290) seat9 = Label(background_label2, text="") seat9.place(x=110, y=310) self.seats = [None, seat1, seat2, seat3, seat4, seat5, seat6, seat7, seat8, seat9] self.messages_text = Text(self.main_window, height=40, width=45) self.messages_text.grid(row=0, column=1) self.main_window.protocol("WM_DELETE_WINDOW", self.close_main_window) self.main_window.after(1, self.update_main_gui) def on_placing_cb_changed(self, data): position_value = self.positions_map[self.combo_select_seating.get()] #global server_connection client_to_server = clientprotocol_pb2.ClientToServer() client_to_server.select_seat.SetInParent() client_to_server.select_seat.user_id = self.server_connection.status_information.user_id client_to_server.select_seat.seat_index = position_value # print("Send message") self.server_connection.send_message_to_server(client_to_server) def on_select_placing(self): self.sub_processes.stop_processes() self.sub_processes.start_processes(self.server_connection.status_information.get_my_seat()) def on_search_for_rebus(self): client_to_server = clientprotocol_pb2.ClientToServer() client_to_server.search_for_rebus.SetInParent() client_to_server.search_for_rebus.dummy = 0; self.server_connection.send_message_to_server(client_to_server) self.rebus_button["text"] = "Letar efter rebus" self.rebus_button["state"] = "disabled" def update_main_gui(self): speed = self.server_connection.get_current_speed() locked = speed != 0 state = "normal" if locked: state = "disabled" self.placing_label["text"] = "Bussen står inte stilla" else: self.placing_label["text"] = "Välj plats i bussen:" if self.server_connection.status_information.looking_for_rebus: self.rebus_button["text"] = "Letar efter rebuskontroll" self.rebus_button["state"] = "disabled" else: self.rebus_button["text"] = "Leta efter rebuskontroll här" self.rebus_button["state"] = state self.combo_select_seating["state"] = state for i in range(1, 10): self.seats[i]["text"] = self.server_connection.status_information.seating[i].name self.main_window.after(1000, self.update_main_gui) def on_message_received(self, bc_message): # global messages_text if bc_message.HasField("date_time"): self.messages_text.insert(END, bc_message.date_time + "\n") if bc_message.HasField("message"): self.messages_text.insert(END, bc_message.message + "\n\n") self.messages_text.yview_pickplace("end") self.main_window.bell() def close_main_window(self): self.sub_processes.stop_processes() self.server_connection.stop() if self.main_window is not None: self.main_window.quit() self.main_window = None def on_lost_connection(self): if self.main_window is not None: try: messagebox.showerror("Förlorad koppling", "Förlorade kopplingen till servern", parent=self.main_window) except: pass self.close_main_window()
class Timer: def __init__(self,pump,rate_vol_pairs,times,master,units): self.root = Toplevel(master) #Check file path and make directories self.path = "C:\\Users\\dkhlab\\Documents\\Experiments"+"\\"+time.asctime().replace(":","-") self.pump = pump self.units = units self.times = times self.rate_vol_pairs =rate_vol_pairs self.pump.sendRun(self.rate_vol_pairs,units) self.root.geometry("400x200") self.start_time = time.time() self.on = True self.elapsed_time = 0 self.root self.pause_time = 0 self.resume_time = None self.m = 0 self.s = 0 self.count = 0 self.label = Label(self.root,text="", font=("Helvetica 35 bold")) q=Button(self.root , text='Close Window', command=self.root.destroy) pb=Button(self.root , text='Pause Experiment', command=self.Pause) rb = Button(self.root , text='Resume Experiment', command=self.Resume) self.label.place(x=160,y=10) pb.place(x=25,y=100) rb.place(x=150,y=100) q.place(x=300,y=100) os.mkdir(self.path) self.vid = Video(self.path) self.Update() self.root.mainloop() #Updates the displayed timer def Update(self,timePaused=0): if self.on: self.elapsed_time = time.time() - self.start_time - timePaused t = self.elapsed_time self.m = int(t/60) self.s = round(t%60) if round(t) in self.times: #takePic(self.path,self.count) self.count += 1 if self.s <10: txt = f"{self.m}:0{self.s}" else: txt = f"{self.m}:{self.s}" self.label.configure(text=txt) self.root.after(1000,self.Update) #Pauses Timer def Pause(self): self.on = False self.pause_time = time.time() self.pump.Pause() self.vid.pause() #Resumes Timer def Resume(self): if self.on is False: self.on = True timePaused = time.time()- self.pause_time self.Update(timePaused) self.pump.Resume() self.vid.play()