def __init__(self, msg, b1, b2, frame, t, entry): root = self.root = tkinter.Tk() root.title('Message') dnd = TkDND(root) self.msg = str(msg) # ctrl+c to copy self.msg root.bind('<Control-c>', func=self.to_clip) # remove the outer frame if frame=False if not frame: root.overrideredirect(True) # default values for the buttons to return self.b1_return = True self.b2_return = False # if b1 or b2 is a tuple unpack into the button text & return value if isinstance(b1, tuple): b1, self.b1_return = b1 if isinstance(b2, tuple): b2, self.b2_return = b2 # main frame frm_1 = tkinter.Frame(root) frm_1.pack(ipadx=2, ipady=2) # the message message = tkinter.Label(frm_1, text=self.msg) message.pack(padx=8, pady=8) # if entry=True create and set focus if entry: self.entry = tkinter.Entry(frm_1) self.entry.pack() self.entry.focus_set() dnd.bindtarget(self.entry, self.set_msg, 'text/uri-list') # button frame frm_2 = tkinter.Frame(frm_1) frm_2.pack(padx=4, pady=4) # buttons btn_1 = tkinter.Button(frm_2, width=8, text=b1) btn_1['command'] = self.b1_action btn_1.pack(side='left') if not entry: btn_1.focus_set() btn_2 = tkinter.Button(frm_2, width=8, text=b2) btn_2['command'] = self.b2_action btn_2.pack(side='left') # the enter button will trigger the focused button's action btn_1.bind('<KeyPress-Return>', func=self.b1_action) btn_2.bind('<KeyPress-Return>', func=self.b2_action) # roughly center the box on screen # for accuracy see: http://stackoverflow.com/a/10018670/1217270 root.update_idletasks() xp = (root.winfo_screenwidth() // 2) - (root.winfo_width() // 2) yp = (root.winfo_screenheight() // 2) - (root.winfo_height() // 2) geom = (root.winfo_width(), root.winfo_height(), xp, yp) root.geometry('{0}x{1}+{2}+{3}'.format(*geom)) # call self.close_mod when the close button is pressed root.protocol("WM_DELETE_WINDOW", self.close_mod) # a trick to activate the window (on windows 7) root.deiconify() # if t is specified: call time_out after t seconds if t: root.after(int(t * 1000), func=self.time_out)
class Redir(object): # This is what we're using for the redirect, it needs a text box def __init__(self, textbox): self.textbox = textbox self.textbox.config(state=NORMAL) self.fileno = sys.stdout.fileno def write(self, message): # When you set this up as redirect it needs a write method as the # stdin/out will be looking to write to somewhere! self.textbox.insert(END, str(message)) root = tkinter.Tk() dnd = TkDND(root) textbox = tkinter.Text() textbox.pack() def handle(event): event.widget.insert(END, event.data) content = textbox.get("0.0", tkinter.END) filename = content.split() dnd.bindtarget(textbox, handle, 'text/uri-list') #Set up the redirect stdre = Redir(textbox)
def __init__(self): self.tk_root = tk.Tk() self.tk_root.geometry('+300+100') self.tk_root.title('Please drop in *.raw file to draw!') # has not been loaded yet self.signal, self.sampling_rates = None, None self.signal_length = -1 # in seconds # add signal figure self.time_interval = 10 self.figure = Figure(figsize=(15, 12), dpi=100) self.canvas = FigureCanvasTkAgg(self.figure, master=self.tk_root) self.canvas.get_tk_widget().grid(row=0, columnspan=3, sticky='NSEW') self.axes = None self.lines = None # set resizable self.tk_root.columnconfigure(0, weight=1) self.tk_root.rowconfigure(0, weight=100) # control units self.time_frame = tk.Frame(borderwidth=10) self.time_frame.grid(row=1, column=0, columnspan=8, sticky='NSEW') # set resizable self.tk_root.columnconfigure(0, weight=1) self.tk_root.rowconfigure(1, weight=1) # add rescale button self.rescale_button = tk.Button(self.time_frame, width=5, text='Rescale', command=self.rescale_plot) self.rescale_button.pack(side=tk.LEFT, padx=5) # add slider bar for time self.time_slider = tk.Scale(self.time_frame, from_=0, to=self.signal_length-self.time_interval-1, resolution=self.time_interval // 2, length=1200, showvalue='no', orient='horizontal', command=self.time_slider_callback) self.time_slider.pack(side=tk.LEFT, padx=5, expand=True, fill='both') # add time input self.time_box_hour = tk.Entry(self.time_frame, validate='key', width=3, validatecommand=self.get_numerical_check(), justify=tk.RIGHT) self.time_box_min = tk.Entry(self.time_frame, validate='key', width=3, validatecommand=self.get_numerical_check(), justify=tk.RIGHT) self.time_box_sec = tk.Entry(self.time_frame, validate='key', width=3, validatecommand=self.get_numerical_check(), justify=tk.RIGHT) self.time_box_sec.pack(sid=tk.RIGHT) tk.Label(self.time_frame, text=':', width=1).pack(sid=tk.RIGHT) self.time_box_min.pack(sid=tk.RIGHT) tk.Label(self.time_frame, text=':', width=1).pack(sid=tk.RIGHT) self.time_box_hour.pack(sid=tk.RIGHT) # bind enter to input boxes self.time_box_hour.bind('<Return>', self.time_box_callback) self.time_box_min.bind('<Return>', self.time_box_callback) self.time_box_sec.bind('<Return>', self.time_box_callback) # support drag and drop self.dnd = TkDND(self.tk_root) self.dnd.bindtarget(self.canvas.get_tk_widget(), self.load_data, 'text/uri-list') # bind left and right arrow keys to move through time self.tk_root.bind('<Left>', self.go_back_time) self.tk_root.bind('<Right>', self.go_to_future) self.tk_root.bind('<space>', self.rescale_plot) self.tk_root.bind('<Up>', self.increase_time_interval) self.tk_root.bind('<Down>', self.decrease_time_interval)
class App: def __init__(self): self.tk_root = tk.Tk() self.tk_root.geometry('+300+100') self.tk_root.title('Please drop in *.raw file to draw!') # has not been loaded yet self.signal, self.sampling_rates = None, None self.signal_length = -1 # in seconds # add signal figure self.time_interval = 10 self.figure = Figure(figsize=(15, 12), dpi=100) self.canvas = FigureCanvasTkAgg(self.figure, master=self.tk_root) self.canvas.get_tk_widget().grid(row=0, columnspan=3, sticky='NSEW') self.axes = None self.lines = None # set resizable self.tk_root.columnconfigure(0, weight=1) self.tk_root.rowconfigure(0, weight=100) # control units self.time_frame = tk.Frame(borderwidth=10) self.time_frame.grid(row=1, column=0, columnspan=8, sticky='NSEW') # set resizable self.tk_root.columnconfigure(0, weight=1) self.tk_root.rowconfigure(1, weight=1) # add rescale button self.rescale_button = tk.Button(self.time_frame, width=5, text='Rescale', command=self.rescale_plot) self.rescale_button.pack(side=tk.LEFT, padx=5) # add slider bar for time self.time_slider = tk.Scale(self.time_frame, from_=0, to=self.signal_length-self.time_interval-1, resolution=self.time_interval // 2, length=1200, showvalue='no', orient='horizontal', command=self.time_slider_callback) self.time_slider.pack(side=tk.LEFT, padx=5, expand=True, fill='both') # add time input self.time_box_hour = tk.Entry(self.time_frame, validate='key', width=3, validatecommand=self.get_numerical_check(), justify=tk.RIGHT) self.time_box_min = tk.Entry(self.time_frame, validate='key', width=3, validatecommand=self.get_numerical_check(), justify=tk.RIGHT) self.time_box_sec = tk.Entry(self.time_frame, validate='key', width=3, validatecommand=self.get_numerical_check(), justify=tk.RIGHT) self.time_box_sec.pack(sid=tk.RIGHT) tk.Label(self.time_frame, text=':', width=1).pack(sid=tk.RIGHT) self.time_box_min.pack(sid=tk.RIGHT) tk.Label(self.time_frame, text=':', width=1).pack(sid=tk.RIGHT) self.time_box_hour.pack(sid=tk.RIGHT) # bind enter to input boxes self.time_box_hour.bind('<Return>', self.time_box_callback) self.time_box_min.bind('<Return>', self.time_box_callback) self.time_box_sec.bind('<Return>', self.time_box_callback) # support drag and drop self.dnd = TkDND(self.tk_root) self.dnd.bindtarget(self.canvas.get_tk_widget(), self.load_data, 'text/uri-list') # bind left and right arrow keys to move through time self.tk_root.bind('<Left>', self.go_back_time) self.tk_root.bind('<Right>', self.go_to_future) self.tk_root.bind('<space>', self.rescale_plot) self.tk_root.bind('<Up>', self.increase_time_interval) self.tk_root.bind('<Down>', self.decrease_time_interval) def increase_time_interval(self, _): self.time_interval = min(3600, self.time_interval * 2) self.time_slider.configure(resolution=self.time_interval // 2) print('Time interval:', self.time_interval, 'sec') self.initial_plot() self.update_plot(self.time_slider.get()) def decrease_time_interval(self, _): self.time_interval = max(10, self.time_interval // 2) self.time_slider.configure(resolution=self.time_interval // 2) print('Time interval:', self.time_interval, 'sec') self.initial_plot() self.update_plot(self.time_slider.get()) def go_to_future(self, _): sec = self.time_slider.get() sec = min(self.signal_length-self.time_interval-1, sec+self.time_interval) self.time_slider.set(sec) self.time_slider_callback(sec) def go_back_time(self, _): sec = self.time_slider.get() sec = max(0, sec-self.time_interval) self.time_slider.set(sec) self.time_slider_callback(sec) def time_box_callback(self, _): hours = int(self.time_box_hour.get()) minutes = int(self.time_box_min.get()) seconds = int(self.time_box_sec.get()) total_sec = hours*60*60 + minutes*60 + seconds total_sec = min(self.signal_length-self.time_interval-1, total_sec) # reset box contant self.time_slider.set(total_sec) self.set_time_of_box(int(total_sec)) self.update_plot(int(total_sec)) def load_data(self, event): filename = re.sub(r'^\{|}$', '', event.data) # remove {} in the begining or the end if any self.tk_root.title(filename) self.signal, self.sampling_rates = reader.get_heart_sounds(filename) self.signal_length = self.signal[0].shape[0] // self.sampling_rates[0] # in seconds self.time_slider.configure(to=self.signal_length-self.time_interval-1) self.time_slider.set(0) self.initial_plot() def rescale_plot(self, _=None): for ax in self.axes: ax.relim() ax.autoscale_view() self.canvas.draw() def get_numerical_check(self): def valid(action, index, value_if_allowed, prior_value, text, validation_type, trigger_type, widget_name): return True if re.match(r'^[0-9]*$', value_if_allowed) else False return (self.tk_root.register(valid), '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W') def set_time_of_box(self, time_in_sec): self.time_box_hour.delete(0, tk.END) self.time_box_min.delete(0, tk.END) self.time_box_sec.delete(0, tk.END) self.time_box_hour.insert(0, str(time_in_sec // 60 // 60)) self.time_box_min.insert(0, str((time_in_sec // 60) % 60)) self.time_box_sec.insert(0, str(time_in_sec % 60)) def time_slider_callback(self, time_in_sec): self.set_time_of_box(int(time_in_sec)) self.update_plot(int(time_in_sec)) @staticmethod def sec_to_timestring(sec): return str(datetime.timedelta(seconds=int(sec))) def initial_plot(self): self.figure.clf() start_s = 0 end_s = start_s + self.time_interval self.axes = list() self.lines = list() for index_channel, (channel_data, sampling_rate) in enumerate(zip(self.signal, self.sampling_rates)): ax = self.figure.add_subplot(self.signal.shape[0], 1, index_channel+1) channel_data = channel_data[ int(start_s*sampling_rate): int(end_s*sampling_rate)] line, = ax.plot(channel_data) ax.set_xticks(np.linspace(0., self.time_interval*sampling_rate, num=10)) ax.set_xticklabels([self.sec_to_timestring(s) for s in np.linspace(start_s, end_s, num=10)]) ax.margins(x=0, y=0) self.lines.append(line) self.axes.append(ax) self.figure.tight_layout() self.canvas.draw() def update_plot(self, start_time): if self.signal is None: return start_s = start_time end_s = start_s + self.time_interval for index_channel, (ax, line, channel_data, sampling_rate) in enumerate(zip(self.axes, self.lines, self.signal, self.sampling_rates)): channel_data = channel_data[ int(start_s*sampling_rate): int(end_s*sampling_rate)] ax.set_xticks(np.linspace(0., self.time_interval*sampling_rate, num=10)) ax.set_xticklabels([self.sec_to_timestring(s) for s in np.linspace(start_s, end_s, num=10)]) line.set_ydata(channel_data) self.canvas.draw() def loop(self): self.tk_root.mainloop()
inputBox = ttk.Entry(top_frame) # root.update() inputBox.pack(side=LEFT, fill=X, expand=True, padx=5, ipady=1) inputBox.focus_set() browseButton1 = ttk.Button(top_frame, text="Browse", command=openFile) browseButton1.pack(side=LEFT) dndframe = Canvas(root, highlightthickness=1, relief="solid", highlightbackground="#c5c5c5") dndframe.pack(fill=BOTH, expand=True, padx=10) dnd = TkDND(root) dnd.bindtarget(dndframe, handle_dnd, "text/uri-list") bottom_frame = Frame(root, bg=base_color) bottom_frame.pack(fill=X, padx=10, pady=10) outputLabel = Label(bottom_frame, text="Output File", bg=base_color) outputLabel.pack(side=LEFT) outputBox = ttk.Entry(bottom_frame) # root.update() outputBox.pack(side=LEFT, fill=X, expand=True, padx=5, ipady=1) browseButton2 = ttk.Button(bottom_frame, text="Browse", command=outpFile) browseButton2.pack(side=LEFT)
import sys import os import Tkinter from tkdnd_wrapper import TkDND import shlex, subprocess from subprocess import Popen, PIPE import glob import shutil root = Tkinter.Tk() dnd = TkDND(root) entry = Tkinter.Entry() entry.grid() def handle(event): inputfilespath = event.data event.widget.insert(0, inputfilespath) filesdir = os.path.dirname(os.path.realpath(inputfilespath)) files = glob.iglob(os.path.join(filesdir, "*.myext")) for inputfilespath in files: if os.path.isfile(inputfilespath): subprocess1 = subprocess.Popen([...conversion command given as list, not string...], shell=True) print "\n\nConversione in corso..." subprocess1.wait() subprocess1.terminate() print "\n\nProcesso terminato!" dnd.bindtarget(entry, handle, 'text/uri-list') root.mainloop()
def __init__(self, master): # overarching vars self.dnd = TkDND(master) self.img_file = "" self.aa = None self.user = tk.StringVar() self.n_total = tk.StringVar() # button functions def user_select(*args): # init db button self.queue = queue.Queue() userget = lambda: self.aa.set_user(self.user.get()) toggle_disable() start_anim() ThreadedTask(self.queue, userget).start() master.after(100, process_queue) def n_select(*args): # number of albums entry try: self.aa.how_many(int(self.n_total.get())) except: return def image_select(): # test button if self.img_file == "": return response = self.aa.tester(self.img_file) TestResults(master, response, self.aa) def test_from_url(*args): # test from url button url = tksimpledialog.askstring("test from url", "pls input url") if not url: return url = url.strip() try: try: response = requests.get(url) except: # i'd rather not but idk response = requests.get(url, verify=False) new_img = Image.open(BytesIO(response.content)) new_img = new_img.resize((300, 300), Image.ANTIALIAS) new_img.save("current_test.png") self.img_file = "current_test.png" self.new_img = ImageTk.PhotoImage(Image.open(self.img_file)) img_canvas.create_image((0, 0), image=self.new_img, anchor=tk.NW) except: self.img_file = "" return image_select() def test_dnd(event, *args): # test button try: if event.data[0] == '{': self.img_file = event.data[1:-1] else: self.img_file = event.data self.new_img = ImageTk.PhotoImage( Image.open(self.img_file).resize((300, 300), Image.ANTIALIAS)) self.albumart = img_canvas.create_image((0, 0), image=self.new_img, anchor=tk.NW) except: self.img_file = "" # tk elements img_canvas = tk.Canvas(master, width=300, height=300) self.new_img = ImageTk.PhotoImage( Image.open('test.png')) # standard image (says drag-n-drop here) self.albumart = img_canvas.create_image((0, 0), image=self.new_img, anchor=tk.NW) start_frame = tk.Frame(master) init_but = tk.Button(start_frame, text='init database', width=30, height=5, command=user_select) user_frame = tk.Frame(start_frame) user_label = tk.Label(user_frame, text='username:'******'center') no_label = tk.Label(user_frame, text='# albums:') no_entry = tk.Spinbox(user_frame, from_=0, to=250, textvariable=self.n_total, justify=tk.RIGHT, width=3) test_frame = tk.Frame(master) test_but = tk.Button(test_frame, text='test', width=30, height=5, command=image_select) test_from_url_but = tk.Button(test_frame, text='from url', width=10, height=5, command=test_from_url) # tk binding self.n_total.trace('w', n_select) self.dnd.bindtarget(img_canvas, test_dnd, 'text/uri-list') # tk packing (layout) img_canvas.pack(side=tk.TOP) test_frame.pack() test_but.pack(side=tk.LEFT) test_from_url_but.pack() init_but.pack(side=tk.LEFT) user_label.pack() user_entry.pack() no_label.pack() no_entry.pack() user_frame.pack(side=tk.RIGHT) start_frame.pack() # animations self.loading_texts = [] self.loading_rects = [] for i in range(4): datext = 'loading' + '.' * i loading_text = img_canvas.create_text((150, 150), text=datext, font="-weight bold -size 16") loading_rect = img_canvas.create_rectangle( img_canvas.bbox(loading_text), fill="gray") img_canvas.tag_lower(loading_rect, loading_text) self.loading_texts.append(loading_text) self.loading_rect = loading_rect # want largest bounding img_canvas.tag_raise(self.albumart) def loading_anim(): if self.anim_counter >= 0: img_canvas.tag_raise(self.loading_rect) img_canvas.tag_raise(self.loading_texts[self.anim_counter]) img_canvas.update() #time.sleep(0.5) self.anim_counter = (self.anim_counter + 1) % 4 master.after(100, loading_anim) def start_anim(): self.anim_counter = 0 loading_anim() def stop_anim(): self.anim_counter = -1 img_canvas.tag_raise(self.albumart) # menubar functions def album_searcher(): AlbumSearch(self.aa) def stat_display(): StatDisp(self.aa) def open_lib(): # first save current self.aa.save_library() # keep track if this works or no self.load_success = False # then ask for new and open it filename = tkfiledialog.askopenfilename(initialdir="./saves") if filename: self.queue = queue.Queue() def load_file(): self.load_success = self.aa.load_from_file(filename) toggle_disable() start_anim() username = filename[filename.rfind('/') + 1:] ThreadedTask(self.queue, load_file).start() p_q = lambda: process_queue_open_lib(username) master.after(100, p_q) # menubar menubar = tk.Menu(master) filemenu = tk.Menu(menubar, tearoff=0) filemenu.add_command(label="open saved library", command=open_lib) filemenu.add_separator() filemenu.add_command(label="about", command=StatDisp) menubar.add_cascade(label='file', menu=filemenu) librarymenu = tk.Menu(menubar, tearoff=0) librarymenu.add_command(label='stats', command=stat_display) librarymenu.add_command(label='search for album to add', command=album_searcher) menubar.add_cascade(label='library', menu=librarymenu) master.config(menu=menubar) # extra functions def toggle_disable(): e_or_d = init_but['state'] == 'normal' for but in [ init_but, test_but, test_from_url_but, user_entry, no_entry ]: if e_or_d: but.config(state='disabled') else: but.config(state='normal') if e_or_d: menubar.entryconfig("file", state='disabled') menubar.entryconfig("library", state='disabled') else: menubar.entryconfig("file", state='normal') menubar.entryconfig("library", state='normal') def start_aa(): self.queue = queue.Queue() def make_aa(): self.aa = AA() toggle_disable() start_anim() ThreadedTask(self.queue, make_aa).start() master.after(100, process_queue_start) def quitter(): self.aa.quit() master.destroy() master.protocol("WM_DELETE_WINDOW", quitter) filemenu.add_command(label="quit", command=quitter) # threading functions def process_queue(): # for init db try: msg = self.queue.get(0) stop_anim() toggle_disable() except queue.Empty: master.after(100, process_queue) def process_queue_open_lib(username): # for open lib (in menu) try: msg = self.queue.get(0) if self.load_success: self.user.set(username) self.aa.username = username print('loaded {0}\'s library'.format(username)) else: self.aa.load_library() stop_anim() toggle_disable() except queue.Empty: do_again = lambda: process_queue_open_lib(username) master.after(100, do_again) def process_queue_start(): try: msg = self.queue.get(0) self.user.set(self.aa.username) self.n_total.set(self.aa.total) stop_anim() toggle_disable() except queue.Empty: master.after(100, process_queue_start) #test_it = tk.Button(master,text='just f my s up',width = 42, height = 5,command = toggle_disable) #stop_it = tk.Button(master,text='just s my f up',width = 42, height = 5,command = stop_anim) #test_it.pack() #stop_it.pack() # ok now everything is rdy #self.aa = AA() # thread me start_aa() master.mainloop()