class PredictionWidget(Frame): """Shows a prediction to the user.""" def __init__(self, master): """Make boxes, register callbacks etc.""" Frame.__init__(self, master) self.active_category = StringVar() self.bind("<Configure>", self.onResize) self.date = None self.predictor = Predictor() self.category_buttons = self.createCategoryButtons() self.text = Label(self, justify=CENTER, font="Arial 14") def createCategoryButtons(self): """Create the buttons used to choose category. Return them.""" result = [] icons = self.readIcons() categories = self.predictor.categories() for i in categories: if i in icons: icon = icons[i] else: icon = icons["= default ="] category_button = Radiobutton(self, image=icon, variable=self.active_category, value=i, indicatoron=False, width=icon_size, height=icon_size, command=self.update) category_button.image_data = icon result.append(category_button) self.active_category.set(categories[0]) return result def readIcons(self): """Read the gui icons from disk. Return them.""" result = {} categories = open(nextToThisFile("icons.txt")).read().split("\n\n") for i in categories: category_name, file_data = i.split("\n", maxsplit=1) image = PhotoImage(data=file_data) result[category_name] = image return result def onResize(self, event): """Rearrange the children when the geometry of self changes.""" if event.widget == self: center = (event.width / 2, event.height / 2) radius = min(center) - icon_size / 2 self.text.place(anchor=CENTER, x=center[0], y=center[1]) for i, j in enumerate(self.category_buttons): turn = 2 * math.pi angle = turn * (1 / 4 - i / len(self.category_buttons)) j.place(anchor=CENTER, x=center[0] + math.cos(angle) * radius, y=center[1] - math.sin(angle) * radius) def update(self, date=None): """Change contents based on circumstances. Set date if given.""" if date: self.date = date if self.date: predictions = self.predictor.predict(self.date) prediction = predictions[self.active_category.get()] prediction = textwrap.fill(prediction, width=20) else: prediction = "" self.text.configure(text=prediction)
class GuiGeneratorSelect(Frame): def __init__(self, parent, generators): Frame.__init__(self, parent) self.parent = parent self.pack() self._generators = generators self._generatorName = StringVar() self._generatorName.set(generators[0].getName()) self._generatorName.trace("w", self._switchSettings) self._generatorLbl = Label(self, text="Generator"); self._generatorLbl.pack(side=LEFT) param = (self, self._generatorName) + tuple(i.getName() for i in generators) self._generatorOpt = OptionMenu(*param) self._generatorOpt.pack(side=LEFT) self._switchSettings() def _switchSettings(self, *args): print("DBG: switch generator settings") for i in self._generators: if i.getName() == self._generatorName.get(): i.pack() self._generatorGui = i print("pack " + str(i.getName())) else: i.pack_forget() print("unpack " + str(i.getName())) def getCurrGeneratorGui(self): return self._generatorGui
class MyFirstGUI: LABEL_TEXT = [ "This is our first GUI!", "Actually, this is our second GUI.", "We made it more interesting...", "...by making this label interactive.", "Go on, click on it again.", ] def __init__(self, master): self.master = master master.title("A simple GUI") self.label_index = 0 self.label_text = StringVar() self.label_text.set(self.LABEL_TEXT[self.label_index]) self.label = Label(master, textvariable=self.label_text) self.label.bind("<Button-1>", self.cycle_label_text) self.label.pack() self.greet_button = Button(master, text="Greet", command=self.greet) self.greet_button.pack() self.close_button = Button(master, text="Close", command=master.quit) self.close_button.pack() def greet(self): print("Greetings!") def cycle_label_text(self, event): self.label_index += 1 self.label_index %= len(self.LABEL_TEXT) # wrap around self.label_text.set(self.LABEL_TEXT[self.label_index])
class KRCCModule: __metaclass__ = ABCMeta def __init__(self): self._terminate = BooleanVar(False) self._id = StringVar(False) @property def terminate(self): return self._terminate.get() @terminate.setter def terminate(self, value): self._terminate.set(value) @property def id(self): return self._id.get() @id.setter def id(self, value): self._id.set(value) @abstractproperty def name(self): pass @abstractmethod def run(self): pass
class Example(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.initUI() def initUI(self): self.parent.title("Listbox") self.pack(fill=BOTH, expand=1) acts = ["Scarlett Johansson", "Rachel Weiss", "Natalie Portman", "Jessica Alba", "Angelina jolie", "Emma Stone", "Sandra Bullock", "Julia Roberts", "Jennifer Lawrence", "Mila Kunis", "Jennifer Aniston", "Charlize Theron", "Cameron Diaz", "Nicole Kidman", "Meryl Streep", "Reese Witherspoon"] lb = Listbox(self, selectmode="multiple") for i in acts: lb.insert(END, i) lb.bind("<<ListboxSelect>>", self.onSelect) lb.pack(pady=15) self.var = StringVar() self.label = Label(self, text=0, textvariable=self.var) self.label.pack() def onSelect(self, val): sender = val.widget idx = sender.curselection() value = sender.get(idx) self.var.set(value)
class Example(Frame): def __init__(self, master): Frame.__init__(self, master) self.dict = {'Asia': ['Japan', 'China', 'India'], 'Europe': ['Portugal', 'Switzerland', 'Ukraine']} self.var_a = StringVar(self) self.var_b = StringVar(self) self.var_a.trace('w', self.update_options) self.option_menu_a = OptionMenu(self, self.var_a, *self.dict.keys()) self.option_menu_a.pack(side="top") self.option_menu_a["width"] = 10 self.option_menu_b = OptionMenu(self, self.var_b, '') self.option_menu_b["width"] = 10 self.option_menu_b.pack(side="top") self.var_a.set('Asia') def update_options(self, *args): countries = self.dict[self.var_a.get()] self.var_b.set(countries[0]) menu = self.option_menu_b['menu'] menu.delete(0, 'end') for c in countries: menu.add_command(label=c, command=lambda x=c: self.var_b.set(x))
class DlgDelay(Dialog): def body(self, master, cfg={}): "place user dialog widgets" self.config = cfg self.config["OK button"] = False self.delay = StringVar() self.delay.set(cfg.get("delay", "")) self.edelay = Entry(master, width=15, textvariable=self.delay) self.edelay.grid(column=1, row=0, sticky="e") Label(master, text=_("Delay:")).grid(column=0, row=0, sticky="w") self.resizable(width=0, height=0) return self.edelay def validate(self): try: flt = float(self.delay.get()) except ValueError: return self.edelay if flt < 0 or flt > 5: return self.edelay return None def apply(self): "On ok button pressed" self.config["delay"] = self.delay.get() self.config["OK button"] = True
class InfoFrame(Frame): def __init__(self,master=None, thread=None): Frame.__init__(self, master) self.controlThread=thread self.stringVar=StringVar() self.grid() self.createWidgets() def createWidgets(self): self.inputText=Label(self) if self.inputText != None: self.inputText['textvariable']=self.stringVar self.inputText["width"] = 50 self.inputText.grid(row=0, column=0, columnspan=6) else: pass self.cancelBtn = Button(self, command=self.clickCancelBtn) # need to implement if self.cancelBtn !=None: self.cancelBtn["text"] = "Cancel" self.cancelBtn.grid(row=0, column=6) else: pass def clickCancelBtn(self): print("close the InfoDialog") self.controlThread.setStop() def updateInfo(self, str): self.stringVar.set(str)
def initUI(self, server): self.parent.title("TrackWise Service Manager") self.pack(fill=BOTH, expand = True, padx = 300) # self.centerWindow() menubar = Menu(self.parent) self.parent.config(menu = menubar) fileMenu = Menu(menubar) fileMenu.add_command(label = "Exit", command = self.onExit) menubar.add_cascade(label = "File", menu = fileMenu) svcsMenu = Menu(menubar) svcsMenu.add_command(label = "List Service Status", command = self.onStatus) svcsMenu.add_command(label = "Stop Services", command = self.onStop) svcsMenu.add_command(label = "Start Services", command = self.onStart) menubar.add_cascade(label = "Services", menu = svcsMenu) # svcs = ['TrackWise Tomcat', 'Web Services Tomcat', 'QMD Tomcat', 'Keystone Intake', 'ID Intake', 'TWC'] svcs = server.getservices() hostname = server.gethostname().strip() servertype = server.gettype().strip() frame0 = Labelframe(self, text = "Server Details", borderwidth = 1) frame0.grid(column = 0, row = 0, sticky = W) so = StringVar() svroverview = Message(frame0, textvariable = so, anchor = W, width = 300) svroverview.grid(column = 0, row = 0) sstr = "Server: {}\n".format(hostname) sstr += "Server Type: {}".format(servertype) so.set(sstr) frame1 = Labelframe(self, text = "Service Status", borderwidth = 1) frame1.grid(column = 0, row = 1, sticky = W) l = StringVar() label1 = Message(frame1, textvariable = l , anchor = W) svcscount = 0 lstr = "" for i in svcs: svcscount += 1 lstr += '{} - '.format(i) + ('UP\n' if svcscount % 2 else 'DOWN\n') l.set(lstr) label1.pack(side=TOP, padx = 5, pady = 5) frame4 = Frame(self, relief=RAISED, borderwidth = 1) frame4.grid(column = 0, row = 2, sticky = W) closeButton = Button(frame4, text="Close", command = self.quit) closeButton.grid(column = 0, row = 0) okButton = Button(frame4, text = "OK") okButton.grid(column = 1, row = 0)
class Mjolnir3(KRCCModule): def __init__(self, root): super().__init__() self.root = root self.exception = None self.list_string = StringVar() self.listbox = Listbox(root, listvariable=self.list_string, font='TkFixedFont', width=300) self.load() def establish_connection_and_run(self): error = None dots = 0 connection = None while not self.terminate: try: if connection is None: connection = krpc.connect(name=self.name) self.run_with_connection(connection) error = None dots = 0 except Exception as e: if error != e.args[0]: error = e.args[0] print('\n') print(traceback.format_exc()) sys.stdout.write('Retrying...\n') if dots > 80: dots = 0 sys.stdout.write('\n') sys.stdout.write('.') dots += 1 sys.stdout.flush() time.sleep(1) if connection is not None: connection.close() def run_with_connection(self, connection): logging.debug('KRPC connection established') strategy = PreLaunch(connection) while not self.terminate: strategy = strategy.update() self.list_string.set(tuple(strategy.display())) def run(self): try: self.establish_connection_and_run() self.listbox.destroy() except RuntimeError: # Should only happen when KeyboardInterrupt is thrown in the MainThread. pass @property def name(self): return 'Mjolnir 3' def load(self): self.listbox.pack(side=LEFT, fill=BOTH)
class Example(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.initUI() def initUI(self): self.parent.title("Listbox") self.pack(fill=BOTH, expand=1) acts = ['Scarlett Johansson', 'Rachel Weiss', 'Natalie Portman', 'Jessica Alba'] lb = Listbox(self) for i in acts: lb.insert(END, i) lb.bind("<<ListboxSelect>>", self.onSelect) lb.place(x=20, y=20) self.var = StringVar() self.label = Label(self, text=0, textvariable=self.var) self.label.place(x=20, y=210) def onSelect(self, val): sender = val.widget idx = sender.curselection() value = sender.get(idx) self.var.set(value)
def undo (self): if len(self.history_list) > 1: a = self.history_list.pop(len(self.history_list) - 1) a = self.history_list[len(self.history_list) -1] StringVar.set(self, a) else: a = self.history_list[0] StringVar.set(self, a)
class OptionMenu45(OptionMenu): def __init__(self,parent,title,option_list,**config): self.result = StringVar() self.result.set(title) OptionMenu.__init__(self,parent,self.result,*option_list,**config) def get(self): return self.result.get()
def test_CheckbuttonWithVar(): parent = Tk() var = StringVar(master=parent) var.set(1) box = CheckbuttonWithVar(parent, var) box.deselect() assert var.get() == '0' parent.destroy()
class FeasDisp(ttk.Frame): """Widget for displaying all of the feasible states in the conflict.""" def __init__(self, master=None, conflict=None, *args): """Initialize the widget.""" ttk.Frame.__init__(self, master, padding=5) self.columnconfigure(1, weight=1) self.rowconfigure(2, weight=1) self.conflict = conflict self.dispFormat = StringVar(value='pattern') self.dispList = StringVar() self.feasList = [] self.fmts = {'Pattern': 'YN-', 'List (YN)': 'YN', 'List (ordered and [decimal])': 'ord_dec'} cBoxOpts = ('Pattern', 'List (YN)', 'List (ordered and [decimal])') self.feasText = ttk.Label(self, text='Feasible States') self.feasText.grid(row=0, column=0, columnspan=3) self.cBox = ttk.Combobox(self, textvariable=self.dispFormat, values=cBoxOpts, state='readonly') self.cBoxLb = ttk.Label(self, text='Format:') self.feasLBx = Listbox(self, listvariable=self.dispList) self.scrl = ttk.Scrollbar(self, orient=VERTICAL, command=self.feasLBx.yview) # ########### self.cBoxLb.grid(column=0, row=1, sticky=NSEW, pady=3) self.cBox.grid(column=1, row=1, columnspan=2, sticky=NSEW, pady=3) self.feasLBx.grid(column=0, row=2, columnspan=2, sticky=NSEW) self.scrl.grid(column=2, row=2, sticky=NSEW) self.cBox.bind('<<ComboboxSelected>>', self.fmtSel) self.feasLBx.configure(yscrollcommand=self.scrl.set) self.dispFormat.set('Pattern') self.fmtSel() def fmtSel(self, *args): """Action on selection of a new format.""" self.refreshList() def setFeas(self, feasList): """Change the list of feasible states to be displayed.""" self.feasList = feasList self.refreshList() def refreshList(self): """Update the list of feasible states displayed and the format.""" fmt = self.fmts[self.dispFormat.get()] if fmt == "YN-": feas = self.conflict.feasibles.dash if fmt == "YN": feas = self.conflict.feasibles.yn if fmt == "ord_dec": feas = self.conflict.feasibles.ordDec self.dispList.set(tuple(feas))
class DiceTab(Frame): def __init__(self,master=None): Frame.__init__(self,master) #Sides of Dice labelSides=Label(self,text="Sides") labelSides.grid(row=0,column=0) self.sides=StringVar() self.sides.set(20) spinboxSides=Spinbox(self,from_=1,to=20,increment=1,width=4) spinboxSides.config(textvariable=self.sides, font="sans 24", justify="center") spinboxSides.grid(row=0,column=1) #Number of Dices labelNumber=Label(self,text="Number") labelNumber.grid(row=1,column=0) self.number=StringVar() self.number.set(1) spinboxNumber=Spinbox(self,from_=1,to=30,increment=1,width=4) spinboxNumber.config(textvariable=self.number, font="sans 24", justify="center") spinboxNumber.grid(row=1,column=1) #Modifier labelModifier=Label(self,text="Modifier") labelModifier.grid(row=2,column=0) self.modifier=StringVar() self.modifier.set(0) spinboxModifier=Spinbox(self,from_=-5,to=5,increment=1,width=4) spinboxModifier.config(textvariable=self.modifier, font="sans 24", justify="center") spinboxModifier.grid(row=2,column=1) #Hide Checkbox labelHide=Label(self, text="Hide") labelHide.grid(row=2, column=2) self.hide=IntVar() self.hide.set(0) checkbuttonHide=Checkbutton(self,variable=self.hide) checkbuttonHide.grid(row=2,column=3) #Result display self.result=StringVar() self.result.set("") labelResult1=Label(self,text="Result") labelResult1.grid(row=1, column=4) labelResult2=Label(self,text=self.result.get(),relief=SUNKEN,width=4) labelResult2.grid(row=1,column=5) #Button to roll buttonRoll=Button(self,text="Roll!", command=self.roll) buttonRoll.grid(row=2,column=5) def roll(self): self.throws=[] numberOfDices=int(self.number.get()) sidesOfDice=int(self.sides.get()) modifierOfDice=int(self.modifier.get()) for i in range(numberOfDices): self.throws.append(rd.randint(1,sidesOfDice)) self.result.set(str(sum(self.throws)+modifierOfDice)) labelResult2=Label(self,text=self.result.get(),relief=SUNKEN, width=4) labelResult2.grid(row=1,column=5)
def create_combo(self, j): """ Create the j'th power / race combo to display in frame_combos. """ combo_textvar = StringVar() combo_textvar.set(self.game.powers[j] + "-" + self.game.races[j]) button_combo = Button(self.frame_combos, textvariable = combo_textvar, state = "disabled", name = "combo_" + str(j), command = lambda: self.press_choose_jth_combo(j)) button_combo.grid(row = 5 - j) self.combos[j] = {"button": button_combo}
class FrameKSPObject(Frame): def __init__(self, master=None): Frame.__init__(self, master) self.pack() frame = Frame(self) frame.pack() self.string_var0 = StringVar() self.string_var1 = StringVar() self.int_var = IntVar() self.entry0 = Entry(frame, textvariable=self.string_var0) self.entry0.pack(side='left') Entry(frame, textvariable=self.string_var1).pack(side='left') frame = Frame(self) frame.pack() Button(frame, width=8, text='Accept', command=self.accept).pack(side='left') Button(frame, width=8, text='Cancel', command=self.cancel).pack(side='left') Button(frame, width=8, text='Delete', command=self.delete).pack(side='left') def populate(self, kspobject): self._kspobject = kspobject self.string_var0.set(kspobject.name) self.string_var1.set(kspobject.value) self.int_var.set(kspobject.id_) def accept(self): name = self.string_var0.get() value = self.string_var1.get() id_ = self.int_var.get() self.master.master.update_kspobject(name, value, id_) self.master.destroy() def cancel(self): self.master.destroy() def delete(self): id_ = self.int_var.get() self.master.master.delete_kspobject(id_) self.master.destroy()
def fourth_window(root, info): store = StringVar() def next_window(root=root, info=info): info['format'] = store.get() fifth_window(root=root, info=info) info['brandname'] = brand.get() info['campaign'] = campaign.get() def back(info=info): third_window(root=root, info=info) def active_next(*args): send.state(['!disabled', 'active']) c = ttk.Frame(root) c.grid(column=0, row=0, sticky=(N, W, E, S)) background_image = tkinter.PhotoImage(file='%s/Desktop/natappy/images/road.gif' % home) background_label = tkinter.Label(c, image=background_image) background_label.image = background_image background_label.place(x=0, y=0, relwidth=1, relheight=1) root.grid_columnconfigure(0, weight=3) root.grid_rowconfigure(0, weight=3) g2 = ttk.Radiobutton(c, text='Full Report', variable=store, value='Full', command=active_next) g2.grid(column=1, row=2, sticky=(N, W, E, S), padx=20, pady=20) g4 = ttk.Radiobutton(c, text='Quick Report', variable=store, value='Quick', command=active_next) g4.grid(column=1, row=4, sticky=(N, W, E, S), padx=20, pady=20) w = Label(c, text="First Page Title") w.grid(column=1, row=5, sticky=(S, W), padx=(20, 5), pady=(5, 0)) brand = Entry(c, width=20) brand.grid(column=1, row=6, sticky=W, padx=(20, 5), pady=(5, 0)) campaign = Entry(c, width=20) campaign.grid(column=2, row=6, sticky=W, padx=(5, 70), pady=(5, 0)) send = ttk.Button(c, text='Next', command=next_window, default='active', state='disabled') send.grid(column=3, row=7, pady=20, sticky=E, padx=(2, 20)) close = ttk.Button(c, text='Back', command=back, default='active') close.grid(column=2, row=7, pady=20, sticky=E) if info['format']: store.set(info['format']) active_next() c.grid_columnconfigure(0, weight=1) c.grid_rowconfigure(5, weight=1) root.title('4/5 Format') root.geometry('550x400+440+200')
class OptionMenu45Whiten(OptionMenu45): def __init__(self,parent,title,option_list,whiten_entry=None,**config): self.whiten_entry = whiten_entry self.result = StringVar() self.result.set(title) OptionMenu45.__init__(self,parent,title,option_list,command=self.whiten,**config) def whiten(self,option): self.whiten_entry.config(bg="white")
class Scroller(object): """ Scrolls through a solution list. """ def __init__(self, wdw, sols): """ Stores the list of solutions in sols and defines the layout of the GUI. """ wdw.title('solutions scroller') self.sols = sols self.cursor = 0 self.lbl = Label(wdw, text="solution : ") self.lbl.grid(row=0, column=0, sticky=E) self.ent = Entry(wdw) self.ent.grid(row=0, column=1, stick=W) self.ent.insert(INSERT, "0 of %d" % len(sols)) self.myft = Font(family="Courier New", size=12, weight="normal") self.mlen = self.myft.measure("M") lines = sols[0].split('\n') self.width = max([len(line) for line in lines]) self.display = StringVar() self.display.set(self.sols[0]) self.mess = Message(wdw, textvariable=self.display, \ font=self.myft, width=self.width*self.mlen, background='white') self.mess.grid(row=1, column=0, columnspan=2) self.btnext = Button(wdw, command=self.next, text='next') self.btnext.grid(row=2, column=1, sticky=W+E) self.btprev = Button(wdw, command=self.previous, text='previous') self.btprev.grid(row=2, column=0, sticky=W+E) def show(self): """ Shows the solution at position self.cursor in the message widget and updates the entry widget. """ self.display.set(self.sols[self.cursor]) self.ent.delete(0, END) self.ent.insert(INSERT, '%d of %d' % (self.cursor, len(self.sols))) def next(self): """ Increases the cursor by one if possible. """ if self.cursor < len(self.sols) - 1: self.cursor = self.cursor + 1 self.show() def previous(self): """ Decreases the cursor by one if possible. """ if self.cursor > 0: self.cursor = self.cursor - 1 self.show()
class LoginGui(object): def __init__(self, root): self.welcome_text = 'Prihlaseny' if User.is_loaded_session() else "" self.response_text = StringVar(root, value=self.welcome_text) self.top_frame = Frame(root, width=400, height=400) self.middle_frame = Frame(root, width=300, height=300) self.top_frame.pack(fill="both", expand=True, padx=20, pady=20) self.middle_frame.place(in_=self.top_frame, anchor='c', relx=.5, rely=.5) self.l_email = Label(self.middle_frame, text="Email") self.e_email = Entry(self.middle_frame) self.l_pass = Label(self.middle_frame, text="Password") self.e_pass = Entry(self.middle_frame, show="*") self.l_sign_up = Label(self.middle_frame, text="Sign up", fg='blue', cursor='hand2') self.l_req_result = Label(self.middle_frame, textvariable=self.response_text) self.b_submit = Button(self.middle_frame, text="Login") self.l_email.grid(row=0, sticky=E) self.e_email.grid(row=0, column=1) self.l_pass.grid(row=1, column=0, sticky=E) self.e_pass.grid(row=1, column=1) self.b_submit.grid(row=2, column=1, sticky=E) self.l_sign_up.grid(row=3, column=1, sticky=E) self.l_req_result.grid(row=4) self.l_sign_up.bind('<Button-1>', self.sing_up_callback) self.b_submit.bind('<Button-1>', self.login) self.root = root self.root.mainloop() def login(self, event): response = User.login(self.e_email.get(), self.e_pass.get()) self.response_text.set(response) if User.is_loaded_session(): self.root.destroy() @staticmethod def sing_up_callback(event): webbrowser.open_new(Config.SIGN_UP_URL) @staticmethod def show_login(): root = tkinter.Tk(className="Productivity optimizer") LoginGui(root) root.mainloop()
class GuiBasicSettings(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.pack() #Unit self.sizeUnits = {"Byte": 1, "KiB":1024, "MiB":1024**2, "GiB":1024**3} self._initFile() self._initSize() def _initFile(self): self._fileLbl = Label(self, text="File: ") self._fileTxt = Entry(self) self._fileTxt.insert(0, "/tmp/out.txt") self._fileBtn = Button(self, text="Create", command=self._callbackFun) self._fileLbl.grid(row=0, column=0) self._fileTxt.grid(row=0, column=1) self._fileBtn.grid(row=0, column=2) def _initSize(self): self._sizeLbl = Label(self, text="FileSize: ") self._sizeTxt = Entry(self) self._sizeTxt.insert(0, "1024") self._sizeVar = StringVar() self._sizeVar.set("Byte") #FIXME: replace "Byte" with variable sizeOptParam = (self, self._sizeVar) + tuple(self.sizeUnits.keys()) self._sizeOptMen = OptionMenu(*sizeOptParam) self._sizeLbl.grid(row=1, column=0) self._sizeTxt.grid(row=1, column=1) self._sizeOptMen.grid(row=1, column=2) def _callbackFun(self): print("_callbackBtn") self.outerCallback() def enableButton(self, enabled=True): if enabled: self._fileBtn.config(state="normal") else: self._fileBtn.config(state="disabled") def getFileName(self): return self._fileTxt.get() def getFileSize(self): mult = int(self.sizeUnits[self._sizeVar.get()]) val = int(self._sizeTxt.get()) return val * mult def setCallback(self, aCallback): self.outerCallback = aCallback
def create_combo(self, j): # create the j'th race / power combo to display in frame_combos. # TODO: how to not call button function upon creation. labmda? # combo_textvar = StringVar() combo_textvar.set(game.powers[j] + "-" + game.races[j]) button_combo = Button(self.frame_combos, textvariable = combo_textvar, state = "disabled", name = "combo_" + str(j), command = lambda: self.choose_combo(j)) button_combo.grid(row = self.num_of_combos - j) self.combos[j] = {"button": button_combo}
class AccountDialog(gui.tksimpledialog.Dialog): def __init__(self, parent, title="", login_name="", password="", path="", dx="dx11"): self.login_name = login_name self.password = password self.path = path self.dx = dx self.entry_ln = None self.variable = None self.entry_pw = None self.entry_path = None self.entry_dx = None super().__init__(parent, title) def body(self, master): Label(master, text="Login Name:").grid(row=0) Label(master, text="Password:"******"Eve Path:").grid(row=2) Label(master, text="DirectX:").grid(row=3) self.entry_ln = Entry(master) self.entry_pw = Entry(master, show="*") self.entry_path = Entry(master) self.variable = StringVar(master) self.variable.set(self.dx) self.entry_dx = OptionMenu(master, self.variable, "dx9", "dx11") self.entry_ln.insert(END, self.login_name) self.entry_pw.insert(END, self.password) self.entry_path.insert(END, self.path) # self.entry_path.bind("<FocusIn>", self.select_eve_path) self.entry_ln.grid(row=0, column=1) self.entry_pw.grid(row=1, column=1) self.entry_path.grid(row=2, column=1) self.entry_dx.grid(row=3, column=1) return self.entry_ln # def select_eve_path(self, event): # if event.widget == self.entry_path: # self.path # res = os.path.normpath(askdirectory(initialdir=self.path)) # self.path = res # self.entry_path.insert(END, res) def apply(self): login_name = self.entry_ln.get() password = self.entry_pw.get() path = self.entry_path.get() dx = self.variable.get() self.result = [login_name, password, path, dx]
class ApplicationController(Tk): def __init__(self, *args, **kwargs): Tk.__init__(self, *args, **kwargs) container = Frame(self) self.title("3d Printer") #This fied is populated on the first view #and displayed on the second self.customer_id = StringVar() container.pack(side="top", fill="both", expand=True) container.grid_rowconfigure(0, weight=1) container.grid_columnconfigure(0, weight=1) self.frames = {} for F in (CreateCustomerView, ExecuteScriptView): frame = F(container, self) self.frames[F] = frame # put all of the pages in the same location; # the one on the top of the stacking order # will be the one that is visible. frame.grid(row=0, column=0, sticky="nsew") self.model = CreateCustomerModel() self.show_frame(CreateCustomerView) def show_frame(self, c): '''Show a frame for the given class''' frame = self.frames[c] frame.tkraise() def save_customer(self, customer): """Save customer and go to next page""" customer_id = self.model.save_customer(customer) if customer_id: self.customer_id.set(customer_id) print(self.customer_id.get()) self.show_frame(ExecuteScriptView) else: messagebox.showerror(message = "All fields are mandatory, please fill in all the fields") def run_take_picture_script(self, customer_id, picture_mode): """Example of executing outside python script""" return self.model.run_take_picture_script(customer_id, picture_mode) def run_update_script(self): pass
class Select_Py_Version(_Dialog): """ Select_Py_Version is a tkinter pop-up dialog used to select a python interpreter for use with Tk_Nosy. """ def body(self, master): dialogframe = Frame(master, width=300, height=300) dialogframe.pack() self.Label_1 = Label(dialogframe, text="Select Python Version") self.Label_1.pack() if self.dialogOptions: rbL = self.dialogOptions.get('rbL', ['No Options','No Options']) else: rbL = ['No Options', 'No Options'] self.RadioGroup1_StringVar = StringVar() self.RadioGroup1_StringVar.set(rbL[0]) self.RadioGroup1_StringVar_traceName = \ self.RadioGroup1_StringVar.trace_variable("w", self.RadioGroup1_StringVar_Callback) for rb in rbL: self.Radiobutton_1 = Radiobutton(dialogframe, text=rb, value=rb) self.Radiobutton_1.pack(anchor=W) self.Radiobutton_1.configure( variable=self.RadioGroup1_StringVar ) self.resizable(0, 0) # Linux may not respect this def RadioGroup1_StringVar_Callback(self, varName, index, mode): """When radio group selection changes, print message to CLI.""" print( "RadioGroup1_StringVar_Callback varName, index, mode", varName, index, mode ) print( " new StringVar value =", self.RadioGroup1_StringVar.get() ) def validate(self): """Validates and packages dialog selections prior to return to calling routine. set values in "self.result" dictionary for return """ self.result = {} # return a dictionary of results self.result["selection"] = self.RadioGroup1_StringVar.get() return 1 def apply(self): print( 'apply called')
class FileInputModel: def __init__(self, title, description, file_types, file_handler): self.title = title self.description = description self.file_types = file_types self.location = None self.location_text = StringVar() self.location_text.set("Nothing yet") self.file_handler = file_handler def open(self): return self.file_handler(self.location)
class Optionmenu(Widget_): def __init__(self, parent_frame, x, y): Widget_.__init__(self, parent_frame, x, y) self.label_width = 15 self.entry_width = 20 self.options = [] self.stringvar = StringVar() self.label = Label(self.widget_frame, width=self.label_width, anchor=E) self.combobox = ttk.Combobox(self.widget_frame, textvariable=self.stringvar, state='readonly' ) self.label.pack(side=LEFT, padx=3) self.combobox.pack(side=LEFT) self.label_bg, self.label_fg, self.label_hover_bg, self.label_hover_fg = None, None, None, None self.entry_bg, self.entry_fg, self.entry_hover_bg, self.entry_hover_fg = None, None, None, None self.combobox_style = ttk.Style() self.combobox_style.configure( 'TCombobox', background='white', selectbackground='white', selectforeground='black', borderwidth=0 ) self.combobox_style.map('TCombobox', fieldbackground=[]) def settings(self, **kwargs): if 'label' in kwargs: self.label.config(text=kwargs['label']) if 'set_option' in kwargs: self.stringvar.set(kwargs['set_option']) if 'add_option' in kwargs: if type(kwargs['add_option']) == list: self.options.extend(kwargs['add_option']) elif type(kwargs['add_option']) == str: self.options.append(kwargs['add_option']) self.combobox['values'] = tuple(self.options) if 'font' in kwargs: self.combobox.config(font=kwargs['font']) if 'label_bg' in kwargs: self.label_bg = kwargs['label_bg'] self.label.config(bg=self.label_bg) if 'label_fg' in kwargs: self.label_fg = kwargs['label_fg'] self.label.config(fg=self.label_fg) pass
def __init__(self, parent, controller): tk.Frame.__init__(self, parent) Home_Button = ttk.Button(self, text = "Home", command = lambda: controller.show_frame(home_module.Home)) Home_Button.grid(column = 3, row = 5, sticky = "nwes") def wavcalc(*args): try: value = float(freq.get()) sol = 299792458 #Define speed of light in meters per second WL = sol / value wave_out.set(WL/1000) except ValueError: freq.set(0) wave_out.set(0) def freq_range_select(*args): value2 = str(range_1.get()) if value2 == 'Hz': range_2.set("kilometers") if value2 == 'kHz': range_2.set("meters") if value2 == 'MHz': range_2.set("millimeters(mm)") if value2 == 'GHz': range_2.set("micrometers(um)") range_1 = StringVar() range_1.set("Hz") range_2 = StringVar() range_2.set("kilometers") ranges = ttk.Combobox(self, textvariable = range_1, state = 'readonly') ranges['values'] = ('Hz', 'kHz', 'MHz', 'GHz') ranges.grid(column = 2, row = 1, sticky = "nwes") ranges.bind('<<ComboboxSelected>>', freq_range_select) freq = StringVar() freq.set(0) wave_out = StringVar() wave_out.set(0) freq_entry = ttk.Entry(self, width = 7, textvariable = freq) freq_entry.grid(column = 2, row = 2, sticky = "nwes") ttk.Label(self, textvariable = wave_out).grid(column = 2, row = 3, sticky = "nwes") ttk.Button(self, text = "Calculate", command = wavcalc).grid(column = 3, row = 4, sticky = "nwes") ttk.Label(self, text = "Please choose a range :").grid(column = 1, row = 1, sticky = "nwes") ttk.Label(self, text = "Please enter a frequency :").grid(column = 1, row = 2, sticky = "nwes") ttk.Label(self, textvariable = range_1).grid(column = 3, row = 2, sticky = "nwes") ttk.Label(self, text = "is equivalent to :").grid(column = 1, row = 3, sticky = "nwes") ttk.Label(self, textvariable = range_2).grid(column = 3, row = 3, sticky = "nwes") for child in W_Calc.winfo_children(self): child.grid_configure(padx = 5, pady = 5) self.bind('<Return>', wavcalc)
class Minesweeper(): #Button style and dimensions BUTTON_HEIGHT = 1 BUTTON_WIDTH = 4 BUTTON_BORDER_WIDTH = 4 BUTTON_STYLE = "raised" GAME_DIFFICULTY_OPTIONS = ["Easy", "Medium", "Hard"] EASY_ROWS = 10 EASY_COLUMNS = 10 EASY_MINES = 10 MEDIUM_ROWS = 20 MEDIUM_COLUMNS = 20 MEDIUM_MINES = 40 HARD_ROWS = 30 HARD_COLUMNS = 30 HARD_MINES = 99 previous_game_difficulty = "Medium" win_flag = True def __init__(self, rows, columns, number_of_mines): self.rows = rows self.columns = columns self.buttons = [] self.number_of_mines = number_of_mines self.flag_count = self.number_of_mines self.start_time = time.time() self.revealed = list(range(0, self.rows * self.columns)) self.revealed[:] = ['nr'] * len(self.revealed) self.flag = list(range(0, self.rows * self.columns)) self.flag[:] = ['nf'] * len(self.flag) self.mine_cells, self.mine_counts = self.load_mines( self.number_of_mines) self.window = Tk() self.window.title("Minesweeper") self.window.config(bg="#9ba2a3") self.upper_frame = Frame(self.window, bg="#9ba2a3") self.lower_frame = Frame(self.window) self.upper_frame.pack() self.lower_frame.pack() self.difficulty = StringVar(self.upper_frame) self.difficulty.set( self.GAME_DIFFICULTY_OPTIONS[self.GAME_DIFFICULTY_OPTIONS.index( self.previous_game_difficulty)]) self.difficulty.trace("w", self.set_difficulty) opt = OptionMenu(self.upper_frame, self.difficulty, *self.GAME_DIFFICULTY_OPTIONS) opt.grid(row=0, column=0, padx=50) self.flag_label = Label(self.upper_frame, text="Flags: " + str(number_of_mines)) self.flag_label.grid(row=0, column=1, padx=50) self.score_display = Label(self.upper_frame, text="Time") self.score_display.after(200, self.timer) self.score_display.grid(row=0, column=2, padx=50) for self.row in range(0, self.rows): for self.column in range(0, self.columns): if self.previous_game_difficulty == "Easy": self.button = Button(self.lower_frame, height=self.BUTTON_HEIGHT, font='sans 10 bold', width=self.BUTTON_WIDTH, borderwidth=self.BUTTON_BORDER_WIDTH, relief=self.BUTTON_STYLE) elif self.previous_game_difficulty == "Medium": self.button = Button(self.lower_frame, height=self.BUTTON_HEIGHT, font='sans 8 bold', width=self.BUTTON_WIDTH, borderwidth=self.BUTTON_BORDER_WIDTH, relief=self.BUTTON_STYLE) elif self.previous_game_difficulty == "Hard": self.button = Button(self.lower_frame, height=self.BUTTON_HEIGHT, font='sans 5 bold', width=self.BUTTON_WIDTH, borderwidth=self.BUTTON_BORDER_WIDTH, relief=self.BUTTON_STYLE) self.position = [self.row, self.column] self.button.bind("<Button-2>", lambda event, position=self.position: self. right_click(event, position)) self.button.bind("<Button-3>", lambda event, position=self.position: self. right_click(event, position)) self.button.bind("<Button-1>", lambda event, position=self.position: self. left_click(event, position)) self.button.grid(row=self.row, column=self.column, sticky="NSEW") self.button.grid_columnconfigure(0, weight=1) self.button.grid_rowconfigure(0, weight=1) self.button.grid_propagate(False) self.buttons.append(self.button) self.BUTTON_DEFAULT_COLOR = self.button.cget('bg') self.window.resizable(False, False) self.window.mainloop() def left_click(self, event, position): row = position[0] column = position[1] if self.flag[self.rows * row + column] == 'f': return self.label_to_button(row, column) def right_click(self, event, position): row = position[0] column = position[1] if self.flag[self.rows * row + column] == 'f' and self.revealed[self.rows * row + column] != 'r': event.widget.configure(bg=self.BUTTON_DEFAULT_COLOR) self.flag[self.rows * position[0] + position[1]] = 'nf' self.flag_count += 1 #this is for upper frame self.flag_label.configure(text="Flags: " + str(self.flag_count)) elif self.revealed[self.rows * row + column] != 'r': if self.flag_count == 0: return event.widget.configure(bg="#808080", state=DISABLED) self.flag[self.rows * position[0] + position[1]] = 'f' self.flag_count -= 1 #this is for upper frame self.flag_label.configure(text="Flags: " + str(self.flag_count)) def timer(self): self.score_display.configure(text="Time: " + str(int(time.time() - self.start_time))) if self.win_flag: self.score_display.after(200, self.timer) def surroundings(self, row, column): surrounding = [] if row != 0 and column != 0 and row != self.rows - 1 and column != self.columns - 1: surrounding.append([(self.rows * (row + 1)) + (column - 1), row + 1, column - 1]) surrounding.append([(self.rows * (row + 1)) + (column), row + 1, column]) surrounding.append([(self.rows * (row + 1)) + (column + 1), row + 1, column + 1]) surrounding.append([(self.rows * (row - 1)) + (column - 1), row - 1, column - 1]) surrounding.append([(self.rows * (row - 1)) + (column), row - 1, column]) surrounding.append([(self.rows * (row - 1)) + (column + 1), row - 1, column + 1]) surrounding.append([(self.rows * row) + column - 1, row, column - 1]) surrounding.append([(self.rows * row) + column + 1, row, column + 1]) elif row == 0 and column == 0: surrounding.append([1, 0, 1]) surrounding.append([self.columns, 1, 0]) surrounding.append([self.columns + 1, 1, 1]) elif row == 0 and column == self.columns - 1: surrounding.append([self.columns - 2, 0, self.columns - 2]) surrounding.append([2 * self.columns - 1, 1, self.columns - 1]) surrounding.append([2 * self.columns - 2, 1, self.columns - 2]) elif row == 0 and column != 0 and column != self.columns - 1: surrounding.append([(self.rows * (row + 1)) + (column - 1), row + 1, column - 1]) surrounding.append([(self.rows * (row + 1)) + (column), row + 1, column]) surrounding.append([(self.rows * (row + 1)) + (column + 1), row + 1, column + 1]) surrounding.append([(self.rows * row) + column + 1, row, column + 1]) surrounding.append([(self.rows * row) + column - 1, row, column - 1]) elif row == self.rows - 1 and column != 0 and column != self.columns - 1: surrounding.append([(self.rows * (row - 1)) + (column - 1), row - 1, column - 1]) surrounding.append([(self.rows * (row - 1)) + (column), row - 1, column]) surrounding.append([(self.rows * (row - 1)) + (column + 1), row - 1, column + 1]) surrounding.append([(self.rows * row) + column + 1, row, column + 1]) surrounding.append([(self.rows * row) + column - 1, row, column - 1]) elif column == 0 and row != 0 and row != self.rows - 1: surrounding.append([(self.rows * (row + 1)) + (column), row + 1, column]) surrounding.append([(self.rows * (row + 1)) + (column + 1), row + 1, column + 1]) surrounding.append([(self.rows * (row - 1)) + (column), row - 1, column]) surrounding.append([(self.rows * (row - 1)) + (column + 1), row - 1, column + 1]) surrounding.append([(self.rows * row) + column + 1, row, column + 1]) elif column == self.columns - 1 and row != 0 and row != self.rows - 1: surrounding.append([(self.rows * (row + 1)) + (column - 1), row + 1, column - 1]) surrounding.append([(self.rows * (row + 1)) + (column), row + 1, column]) surrounding.append([(self.rows * (row - 1)) + (column - 1), row - 1, column - 1]) surrounding.append([(self.rows * (row - 1)) + (column), row - 1, column]) surrounding.append([(self.rows * row) + column - 1, row, column - 1]) elif row == self.rows - 1 and column == 0: surrounding.append([(self.rows * row) + column + 1, row, column + 1]) surrounding.append([(self.rows * (row - 1)) + column, row - 1, column]) surrounding.append([(self.rows * (row - 1)) + column + 1, row - 1, column + 1]) elif column == self.columns - 1 and row == self.rows - 1: surrounding.append([(self.rows * row) + column - 1, row, column - 1]) surrounding.append([(self.rows * (row - 1)) + column, row - 1, column]) surrounding.append([(self.rows * (row - 1)) + column - 1, row - 1, column - 1]) return surrounding def load_mines(self, number_of_mines): mine_cells = list(range(self.rows * self.columns)) mine_cells[0:number_of_mines] = [1] * number_of_mines mine_cells[number_of_mines:] = [0 ] * (len(mine_cells) - number_of_mines) random.shuffle(mine_cells) random.shuffle(mine_cells) mine_counts = [] for row in range(0, self.rows): for column in range(0, self.columns): if mine_cells[self.rows * row + column] == 1: mine_counts.append('b') continue mine_count = 0 surroundings = self.surroundings(row, column) for cell in surroundings: mine_count += mine_cells[cell[0]] mine_counts.append(mine_count) for row in range(0, len(mine_counts)): if int(mine_cells[row]) == 1: mine_cells[row] = 'b' else: mine_cells[row] = mine_counts[row] print('\n') for row in range(0, self.rows): li = [] for column in range(0, self.columns): li.append(mine_cells[self.rows * row + column]) print(li) return mine_cells, mine_counts def label_to_button(self, row, column): if self.revealed[self.rows * row + column] == 'r': return if self.flag[self.rows * row + column] == 'f': self.buttons[self.rows * row + column].configure(bg=self.BUTTON_DEFAULT_COLOR) self.flag[self.rows * row + column] = 'nf' self.flag_count += 1 #this is for upper frame self.flag_label.configure(text="Flags: " + str(self.flag_count)) if self.mine_cells[self.rows * row + column] == 'b': #,height=1,width=3, #mine_image = PhotoImage(file="E:\My git repos\minesweeper-using-tkinter\mines.gif") for k in range(0, self.rows): for l in range(0, self.columns): if self.mine_cells[self.rows * k + l] == 'b': self.buttons[self.rows * k + l].configure( state=DISABLED, bg='#d97707') self.revealed[self.rows * k + l] = 'r' self.mine_counts[self.rows * k + l] = " self.revealed" self.buttons[self.rows * row + column].configure( state=DISABLED, bg='#b03320') self.revealed[self.rows * row + column] = 'r' self.game_lost() return elif self.mine_cells[self.rows * row + column] != 0 and self.mine_cells[self.rows * row + column] != 'b': if self.mine_cells[self.rows * row + column] == 1: self.buttons[self.rows * row + column].configure( fg='green', text=str(self.mine_counts[self.rows * row + column])) elif self.mine_cells[self.rows * row + column] == 2: self.buttons[self.rows * row + column].configure( fg='blue', text=str(self.mine_counts[self.rows * row + column])) else: self.buttons[self.rows * row + column].configure( fg='red', text=str(self.mine_counts[self.rows * row + column])) self.revealed[self.rows * row + column] = 'r' elif self.mine_counts[self.rows * row + column] == 0: def clear_cell(cell_data): if self.revealed[cell_data[0]] == 'r': return elif self.revealed[cell_data[0]] == 'nr' and self.mine_counts[ cell_data[0]] != 0: self.label_to_button(cell_data[1], cell_data[2]) return elif self.mine_counts[cell_data[0]] == 0 and self.revealed[ cell_data[0]] == 'nr': if self.flag[cell_data[0]] == 'f': self.flag_count += 1 #this is for upper frame self.flag_label.configure(text="Flags: " + str(self.flag_count)) self.buttons[self.rows * cell_data[1] + cell_data[2]].configure(state=DISABLED, bg='#0096e0') self.revealed[self.rows * cell_data[1] + cell_data[2]] = 'r' surroundings = self.surroundings(cell_data[1], cell_data[2]) for cell in surroundings: clear_cell(cell) clear_cell([self.rows * row + column, row, column]) win_count = 0 for check_win in range(0, self.rows * self.columns): if self.mine_counts[check_win] != 'b' and self.revealed[ check_win] == 'r': win_count += 1 if win_count == (self.rows * self.columns) - self.number_of_mines: self.win_flag = False self.game_win() def game_win(self): self.score = int(time.time() - self.start_time) self.window.update_idletasks() message_answer = messagebox.askyesno( title="Win Game", message="You swept all the mines " + "\n" + "Score: " + str(self.score) + ". Do you want to play again??") if message_answer: self.new_game() else: self.window.destroy() def game_lost(self): self.window.update_idletasks() message_answer = messagebox.askyesno( title="Better luck next time :(", message="Game lost!!. Do you want to try again??") if message_answer: self.new_game() else: self.window.destroy() def set_difficulty(self, *args): self.new_game() pass def new_game(self): #self.difficulty.get() self.window.destroy() self.set_option = False difficulty = self.difficulty.get() if difficulty == "Easy": self.previous_game_difficulty = "Easy" self.__init__(self.EASY_ROWS, self.EASY_COLUMNS, self.EASY_MINES) if difficulty == "Medium": self.previous_game_difficulty = "Medium" self.__init__(self.MEDIUM_ROWS, self.MEDIUM_COLUMNS, self.MEDIUM_MINES) if difficulty == "Hard": self.previous_game_difficulty = "Hard" self.__init__(self.HARD_ROWS, self.HARD_COLUMNS, self.HARD_MINES)
class ButtonGroup(ContainerTextWidget): def __init__(self, master, options=[], selected=None, horizontal=False, command=None, grid=None, align=None, args=None, visible=True, enabled=None, width=None, height=None): """ Creates a ButtonGroup :param Container master: The Container (App, Box, etc) the ButtonGroup will belong too. :param List option: A list of options to append to the ButtonGroup. If a 2D list is specified, the first element is the text, the second is the value, defaults to an empty list. :param string selected: The item in the ButtonGroup to select, defaults to `None`. :param string horizontal: If the ButtonGroup is to be displayed horizontally, defaults to `True`. :param callback command: The callback function to call when the ButtonGroup changes, defaults to `None`. :param List grid: Grid co-ordinates for the widget, required if the master layout is 'grid', defaults to `None`. :param string align: How to align the widget within the grid, defaults to None. :param callback args: A list of arguments to pass to the widgets `command`, defaults to `None`. :param bool visible: If the widget should be visible, defaults to `True`. :param bool enabled: If the widget should be enabled, defaults to `None`. If `None` the value is inherited from the master. :param int width: The starting width of the widget. Defaults to `None` and will auto size. :param int height: The starting height of the widget. Defaults to `None` and will auto size. """ description = "[ButtonGroup] object with selected option \"" + str( selected) + "\"" self._rbuttons = [] # List of RadioButton objects self._text_size = None self._font = None self._horizontal = horizontal # Create a Tk frame object to contain the RadioButton objects tk = Frame(master.tk) # Set (using StringVar set() method) the selected option **number** self._selected = StringVar(master=tk.winfo_toplevel()) # ButtonGroup uses "grid" internally to sort the RadioButtons super().__init__(master, tk, description, "grid", grid, align, visible, enabled, width, height) # Loop through the list given and setup the options self._options = [] for option in options: self._options.append(self._parse_option(option)) self._refresh_options() # set the initial value if selected is None and len(self._options) > 0: self.value = self._options[0][1] else: self.value = selected # Add a command if there was one self.update_command(command, args) # override the event manager and associate the button group and the # radio buttons to it option_tks = [option.tk for option in self._rbuttons] self._events = EventManager(self, self.tk, *option_tks) # now the ButtonGroup is populate it, size it self.resize(width, height) def _parse_option(self, option): # If only a 1D was provided, use the text value as a key if not isinstance(option, list): return [option, option] else: return [option[0], option[1]] def _refresh_options(self): # destroy any existing radio buttons for button in self._rbuttons: button.destroy() self._rbuttons = [] gridx = 0 gridy = 0 for button in self._options: # Which way the buttons go if self._horizontal: gridx += 1 else: gridy += 1 # Create a radio button object rbutton = RadioButton(self, text=str(button[0]), value=str(button[1]), variable=self._selected, grid=[gridx, gridy], align="left", visible=self.visible, enabled=self.enabled) # Add this radio button to the internal list self._rbuttons.append(rbutton) # Set the callback rbutton.tk.config(command=self._command_callback) # PROPERTIES # ----------------------------------- # Gets the selected value (1, 2, 3 etc.) @property def value(self): """ Sets or returns the option selected in a ButtonGroup. """ return (self._selected.get()) # Sets which option is selected (if it doesn't exist, nothing is selected) @value.setter def value(self, value): self._selected.set(str(value)) # Gets the text of the currently selected option @property def value_text(self): """ Sets or returns the option selected in a ButtonGroup by its text value. """ search = self._selected.get( ) # a string containing the selected option # This is a bit nasty - suggestions welcome for item in self._rbuttons: if item.value == search: return item.text return "" # Selects the option for the value_text provided @value_text.setter def value_text(self, value): for item in self._rbuttons: if item.text == value: self.value = item.value def resize(self, width, height): """ Resizes the widget. :param int width: The width of the widget. :param int height: The height of the widget. """ self._width = width self._height = height # update radio buttons width for item in self._rbuttons: item.width = width # update radio buttons height if len(self._rbuttons) > 0: # work out the height of a button button_height = height if isinstance(height, int): if height % len(self._rbuttons) != 0: # if the height doesnt divide by the number of radio buttons give a warning button_height = int(round(height / len(self._rbuttons))) new_height = button_height * len(self._rbuttons) utils.error_format( "ButtonGroup height '{}' doesn't divide by the number of buttons '{}' setting height to '{}'." .format(height, len(self._rbuttons), new_height)) else: button_height = int(height / len(self._rbuttons)) for item in self._rbuttons: item.height = button_height super().resize(width, height) @property def options(self): """ Returns a list of options in the ButtonGroup """ return self._options # METHODS # ----------------------------------- def append(self, option): """ Appends a new `option` to the end of the ButtonGroup. :param string/List option: The option to append to the ButtonGroup. If a 2D list is specified, the first element is the text, the second is the value. """ self._options.append(self._parse_option(option)) self._refresh_options() self.resize(self._width, self._height) def insert(self, index, option): """ Insert a new `option` in the ButtonGroup at `index`. :param int option: The index of where to insert the option. :param string/List option: The option to append to the ButtonGroup. If a 2D list is specified, the first element is the text, the second is the value. """ self._options.insert(index, self._parse_option(option)) self._refresh_options() self.resize(self._width, self._height) def remove(self, option): """ Removes the first `option` from the ButtonGroup. Returns `True` if an item was removed. :param string option: The value of the option to remove from the ButtonGroup. """ for existing_option in self._options: if existing_option[1] == option: self._options.remove(existing_option) self._refresh_options() return True return False def clear(self): """ Clears all the options in a Combo """ self._options = [] self._refresh_options() self.value = "" # To help with debugging - return list of text/value pairs def get_group_as_list(self): return [[option.text, option.value] for option in self._rbuttons] def update_command(self, command, args=None): """ Updates the callback command which is called when the ButtonGroup changes. Setting to `None` stops the callback. :param callback command: The callback function to call. :param callback args: A list of arguments to pass to the widgets `command`, defaults to `None`. """ if command is None: self._command = lambda: None else: if args is None: self._command = command else: self._command = utils.with_args(command, *args) def _command_callback(self): self._command()
class MainWindow(): """Main GUI window class""" def __init__(self): root = Tk() root.geometry("800x150") root.title("Code Friend") self.search = StringVar() self.search.set("") frame = Frame(root, borderwidth=5) frame.grid(row=0, column=3) search_label = Label(frame, text="Enter What you want to search", font="Helvetica 15 bold", fg="blue") search_label.grid(row=0, column=4) search_textbox = Entry(frame, textvar=self.search, font="lucida 15 italic") search_textbox.grid(row=0, column=5) self.use_google = BooleanVar() google = Checkbutton(text="Google", variable=self.use_google) google.grid(row=1, column=3) self.use_youtube = BooleanVar() yt_checkbutton = Checkbutton(text="Youtube", variable=self.use_youtube) yt_checkbutton.grid(row=2, column=3) self.use_stackoverflow = BooleanVar() so_checkbutton = Checkbutton(text="Stack Overflow", variable=self.use_stackoverflow) so_checkbutton.grid(row=3, column=3) self.use_github = BooleanVar() gh_checkbutton = Checkbutton(text="Github", variable=self.use_github) gh_checkbutton.grid(row=4, column=3) search_button = Button(frame, text="Search", font="lucida 15 italic") search_button.bind("<Button-1>", self.search_button_clicked) search_button.grid(row=0, column=6) root.mainloop() def search_button_clicked(self, event): """Handler of Search Button""" google = self.use_google.get() youtube = self.use_youtube.get() stackoverflow = self.use_stackoverflow.get() github = self.use_github.get() if any([google, youtube, stackoverflow, github]): browser = Browser() request = self.search.get() if google: browser.search_google(request) if youtube: browser.search_youtube(request) if stackoverflow: browser.search_stackoverflow(request) if github: browser.search_github(request) else: msg.showerror("Error", "Please Select a option first!")
class InstallerGui(object): def __init__(self, master): self.master = master self.widgets = OrderedDict() self.string_var = None self.build() self.place() @property def https_host(self): return "https://pyppa.pythonanywhere.com/" def build(self): self.master.title('PyPPA Installer') self.master.geometry("250x190") # width x height # label self.widgets['label'] = {} self.widgets['label']['version'] = Label(master=self.master, text="Select a version:") self.widgets['label']['destination'] = Label( master=self.master, text="Provide a destination path:") # optionmenu options = self.get_versions() self.string_var = StringVar(master=self.master) self.string_var.set(options[0]) self.widgets['optionmenu'] = {} self.widgets['optionmenu']['version'] = OptionMenu( self.master, self.string_var, *options) # entry self.widgets['entry'] = {} self.widgets['entry']['destination'] = Entry(master=self.master, ) self.widgets['entry']['destination'].insert( 0, os.path.expanduser("~")) # default is home directory # button self.widgets['button'] = {} self.widgets['button']['install'] = Button(master=self.master, text="Install", command=self.install) def place(self): x = 10 y = 10 # iterate in an orderly fashion ordered_widgets = [(self.widgets['label']['version'], 25), (self.widgets['optionmenu']['version'], 60), (self.widgets['label']['destination'], 25), (self.widgets['entry']['destination'], 30), (self.widgets['button']['install'], 0)] for w, i in ordered_widgets: w.place(x=x, y=y) y += i def get_versions(self): client_os = platform.system() r = requests.post(url=self.https_host + 'available_versions', data={'os': client_os}) available_versions = json.loads(r.content) available_versions = [ v.replace('.zip', '') for v in available_versions ] return available_versions def install(self): v = self.string_var.get() d = self.widgets['entry']['destination'].get() # initialize the installation object and let it run automatically i = Installation(version=v, destination=d) i.build_destination() i.build_version() i.build_bin() print("Installation complete!") exit()
def register(): global screen1, fullname, email, password, repassword, university, gender, tnc # making all entry field variable global fullname = StringVar() email = StringVar() password = StringVar() repassword = StringVar() university = StringVar() gender = IntVar() tnc = IntVar() screen1 = Toplevel(screen) screen1.title("Registeration") adjustWindow(screen1) # configuring the window Label(screen1, text="Registration Form", width='40', height="2", font=("Calibri", 22, 'bold'), fg='white', bg='#d9660a').place(x=0, y=0) Label(screen1, text="", bg='#174873', width='50', height='17').place(x=45, y=120) Label(screen1, text="Full Name:", font=("Open Sans", 11, 'bold'), fg='white', bg='#174873', anchor='w').place(x=150, y=160) Entry(screen1, textvar=fullname).place(x=300, y=160) Label(screen1, text="Email ID:", font=("Open Sans", 11, 'bold'), fg='white', bg='#174873', anchor='w').place(x=150, y=210) Entry(screen1, textvar=email).place(x=300, y=210) Label(screen1, text="Gender:", font=("Open Sans", 11, 'bold'), fg='white', bg='#174873', anchor='w').place(x=150, y=260) Radiobutton(screen1, text="Male", variable=gender, value=1, bg='#174873').place(x=300, y=260) Radiobutton(screen1, text="Female", variable=gender, value=2, bg='#174873').place(x=370, y=260) Label(screen1, text="University:", font=("Open Sans", 11, 'bold'), fg='white', bg='#174873').place(x=150, y=310) list1 = [ 'Mumbai University', 'Savitribai Phule Pune Univeristy', 'Gujarat Technological University', 'JNTU Kakinada', 'University of Delhi', 'Anna University' ] droplist = OptionMenu(screen1, university, *list1) droplist.config(width=17) university.set('--select your university--') droplist.place(x=300, y=305) Label(screen1, text="Password:"******"Open Sans", 11, 'bold'), fg='white', bg='#174873', anchor='w').place(x=150, y=360) Entry(screen1, textvar=password, show="*").place(x=300, y=360) Label(screen1, text="Re-Password:"******"Open Sans", 11, 'bold'), fg='white', bg='#174873', anchor='w').place(x=150, y=410) entry_4 = Entry(screen1, textvar=repassword, show="*") entry_4.place(x=300, y=410) Checkbutton(screen1, text="I accept all terms and conditions", variable=tnc, bg='#174873', font=("Open Sans", 9, 'bold'), fg='brown').place(x=175, y=450) Button(screen1, text='Submit', width=20, font=("Open Sans", 13, 'bold'), bg='brown', fg='white', command=register_user).place(x=170, y=490)
def AreaConverter(): wind = Toplevel() wind.minsize(width=400, height=150) wind.maxsize(width=400, height=150) meterFactor = { 'square meter': 1, 'square km': 1000000, 'square rood': 1011.7141056, 'square cm': 0.0001, 'square foot': 0.09290304, 'square inch': 0.00064516, 'square mile': 2589988.110336, 'milimeter': 0.000001, 'square rod': 25.29285264, 'square yard': 0.83612736, 'square township': 93239571.9721, 'square acre': 4046.8564224, 'square are': 100, 'square barn': 1e-28, 'square hectare': 10000, 'square homestead': 647497.027584 } def convert(x, fromUnit, toUnit): if fromVar.get() in meterFactor.keys() and toVar.get( ) in meterFactor.keys(): resultxt.delete(0, END) result = (float(str(x)) * meterFactor[fromUnit]) / (meterFactor[toUnit]) resultxt.insert(0, str(result)) titleLabel = Label(wind, text="Area Converter", font=("Arial", 12, "bold"), justify=CENTER).grid(column=1, row=1) e = Entry(wind) e.grid(row=1, column=2) values = list(meterFactor.keys()) fromVar = StringVar(wind) toVar = StringVar(wind) fromVar.set("From Unit") toVar.set("To Unit") fromOption = OptionMenu( wind, fromVar, *values, command=lambda y: convert(e.get(), fromVar.get(), toVar.get())) fromOption.grid(row=1, column=3) toLabel = Label(wind, text="To : ", font="Arial").grid(row=2, column=2) toOption = OptionMenu( wind, toVar, *values, command=lambda x: convert(e.get(), fromVar.get(), toVar.get())) toOption.grid(row=3, column=3) resultxt = Entry(wind) resultxt.grid(row=3, column=2)
def WeightConverter(): # factors to multiply to a value to convert from the following units to meters(m) factors = { 'kg': 1000, 'hg': 100, 'dg': 10, 'g': 1, 'deg': 0.1, 'cg': 0.01, 'mg': 0.001 } ids = { "Kilogram": 'kg', "Hectagram": 'hg', "Decagram": 'dg', "Decigram": 'deg', "Kilogram": 'kg', "gram": 'g', "centigram": 'cg', "milligram": 'mg' } # function to convert from a given unit to another def convert(amt, frm, to): if frm != 'g': amt = amt * factors[frm] return amt / factors[to] else: return amt / factors[to] def callback(): try: amt = float(in_field.get()) except ValueError: out_amt.set('Invalid input') return None if in_unit.get() == 'Select Unit' or out_unit.get() == 'Select Unit': out_amt.set('Input or output unit not chosen') return None else: frm = ids[in_unit.get()] to = ids[out_unit.get()] out_amt.set(convert(amt, frm, to)) # initiate window root = Toplevel() root.title("Weight Converter") # initiate frame mainframe = ttk.Frame(root, padding="3 3 12 12") mainframe.pack(fill=BOTH, expand=1) titleLabel = Label(mainframe, text="Weight Converter", font=("Arial", 25, "bold"), justify=CENTER).grid(column=1, row=1) in_amt = StringVar() in_amt.set('0') out_amt = StringVar() in_unit = StringVar() out_unit = StringVar() in_unit.set('Select Unit') out_unit.set('Select Unit') # Add input field in_field = ttk.Entry(mainframe, width=20, textvariable=in_amt) in_field.grid(row=1, column=2, sticky=(W, E)) # Add drop-down for input unit in_select = OptionMenu(mainframe, in_unit, "Kilogram", "Hectagram", "Decagram", "gram", "Decigram", "Centigram", "Milligram").grid(column=3, row=1, sticky=W) # Add output field and drop-down ttk.Entry(mainframe, textvariable=out_amt, state="readonly").grid(column=2, row=3, sticky=(W, E)) in_select = OptionMenu(mainframe, out_unit, "Kilogram", "Hectagram", "Decagram", "gram", "Decigram", "Centigram", "Milligram").grid(column=3, row=3, sticky=W) calc_button = ttk.Button(mainframe, text="Calculate", command=callback).grid(column=2, row=2, sticky=E) for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5) widget = Button(None, text="QUIT", bg="yellow", fg="blue", font=("Arial", 14, "bold"), relief=SUNKEN, bd=5, justify=CENTER, highlightbackground="red", overrelief=GROOVE, activebackground="green", activeforeground="blue", command=root.destroy) in_field.focus()
class LayoutTester(object): """Gränssnitt för testning av layoutfunktioner.""" def __init__(self, layout_func, debug=False): """Skapa GUI och förbereder tkinter.Labels som ska layoutas. layout_func -- Funktionen som ska placera kvadraterna, se modulbeskrivning ovan. """ self.layout_func = layout_func self.debug = debug # storleksalternativ self.size_options = [ size for size in range(MIN_SQUARE_SIZE, MAX_SQUARE_SIZE + 1, SIZE_STEP) ] + ["random"] # lista för kvadraterna self.squares = [] # skapa gränssnittet och kör igång mainloop self.ui_xpadding = 4 self.ui_ypadding = 4 self.init_ui() # slumpa fram fönsterstorlek w_size = "{}x{}".format(705 + randint(0, 300), 250 + randint(0, 500)) self.root.geometry(w_size) self.root.mainloop() def init_ui(self): """Skapa gränssnittet och kör igång mainloop.""" self.root = Tk() self.root.title("Laboration 5") # root.resizable(width=False, height=False) # Tk-variabler till kvadratsstorlek, antal kvadrater, start_left och # start_top. self.size_value = StringVar() self.size_value.set(self.size_options[0]) self.number_of_squares = IntVar() self.start_left = BooleanVar() self.start_left.set(True) self.start_top = BooleanVar() self.start_top.set(True) # Frame att lägga kvadraterna i self.square_frame = Frame( self.root, # height=self.squares_frame_height, # width=self.squares_frame_width, bg="#eef") if self.debug: self.square_frame.bind("<Configure>", self.frame_changed) self.square_frame.pack(side=TOP, expand=1, fill=BOTH, padx=self.ui_xpadding, pady=self.ui_ypadding) # Frame med inställningar self.controll_panel = LabelFrame(self.root, text="Inställningar") self.init_controll_panel() self.controll_panel.pack(fill=BOTH, padx=self.ui_xpadding, pady=self.ui_ypadding) # Informationstext infotext = "Kom ihåg att ändra fönstrets storlek när du testar! " + \ "Se även utskrifterna i terminalen." self.instructions = Label(self.root, text=infotext) self.instructions.pack(anchor=W) def init_controll_panel(self): """Skapa kontrollpanel för inställningar.""" self.create_size_panel() self.create_num_squares_panel() # self.create_start_pos_panel() self.create_run_quit_panel() def create_size_panel(self): """Skapa OptionMenu för storlek på kvadraterna.""" size_panel = Frame(self.controll_panel) Label(size_panel, text="Kvadratsstorlek").pack(side=LEFT) OptionMenu(size_panel, self.size_value, *self.size_options).pack(side=LEFT) size_panel.pack(side=LEFT, padx=self.ui_xpadding, pady=self.ui_ypadding) def create_num_squares_panel(self): """Skapa kontroller för att välja antal kvadrater som skapas.""" num_squares_panel = Frame(self.controll_panel) Label(num_squares_panel, text="Antal kvadrater").pack(side=LEFT, anchor=S) Scale(num_squares_panel, variable=self.number_of_squares, from_=4, to=MAX_NUM_SQUARES, orient=HORIZONTAL).pack(side=LEFT, anchor=N) num_squares_panel.pack(side=LEFT, anchor=N, padx=self.ui_xpadding, pady=self.ui_ypadding) def create_start_pos_panel(self): """Skapa kontroller för att välja var layouten börjar.""" start_panel = Frame(self.controll_panel) Checkbutton(start_panel, text="Börja från vänster", justify=LEFT, variable=self.start_left, onvalue=True, offvalue=False).pack(fill=X, anchor=N) Checkbutton(start_panel, text="Börja uppifrån", variable=self.start_top, justify=LEFT, onvalue=True, offvalue=False).pack(fill=X, anchor=N) start_panel.pack(side=LEFT, anchor=N, padx=self.ui_xpadding, pady=self.ui_ypadding) def create_run_quit_panel(self): """Skapa knappar för att köra layout och avsluta programmet.""" button_panel = Frame(self.controll_panel) Button(button_panel, text="Kör layoutfunktion", command=self.run_layout).pack(fill=X) Button(button_panel, text="Avsluta", command=self.root.quit).pack(fill=X) button_panel.pack(side=RIGHT, anchor=N, padx=self.ui_xpadding, pady=self.ui_ypadding) def create_squares(self): """Skapa tkinter.Label objekt som sparas i LayoutTester-instansen. Antalet kvadrater som ska skapas, samt kvadraternas storlek hämtas från gränssnittet. """ number_of_squares = self.number_of_squares.get() size = self.size_value.get() square_counter = 0 hue_step = 1 / number_of_squares hue_value = 0 # Skapa kvadrater och lägg dem i listan self.squares while square_counter < number_of_squares: # konververa hsv-färg till rgb-trippel (heltal 0-255) rgb = [int(val * 255) for val in hsv_to_rgb(hue_value, 0.75, 0.70)] # konvertera rgb-trippel till sträng bg_color = "#{:x}{:x}{:x}".format(rgb[0], rgb[1], rgb[2]) # textfärg fg_color = "#fff" # sätt storleken på kvadraten if size != "random": square_size = int(size) else: square_size = choice(self.size_options[:-1]) # sätt storleken på texten baserat på kvadratstorleken font_size = int(square_size * 0.6) # skapa kvadraten square = Label(self.square_frame, fg=fg_color, bg=bg_color, font=Font(family="Verdana", weight=NORMAL, size=font_size), text=str(square_counter + 1)) # spara den i listan med kvadrater self.squares.append(square) # göm kvadraten utanför det synliga området och ställ in # dess storlek square.place(x=-square_size, y=-square_size, height=square_size, width=square_size) # gå vidare till nästa kvadrat och färg square_counter += 1 hue_value += hue_step # uppdatera geometri-info för alla widgets (ser till att de vet hur # stora de är) square.update_idletasks() def clear_squares(self): """Ta bort existerande kvadrater.""" for square in self.squares: square.destroy() del self.squares[:] def frame_changed(self, event): if event.widget == self.square_frame or event.widget == self.root: print("Resize. root: {}x{}, square_frame: {}x{}".format( self.root.winfo_width(), self.root.winfo_height(), self.square_frame.winfo_width(), self.square_frame.winfo_height())) def run_layout(self): """Skapa nya kvadrater och kör layoutfunktionen.""" # ta bort gamla kvadrater self.clear_squares() # skapa nya kvadrater self.create_squares() # placera ut kvadraterna print("Running '{0}(<squares>, {1}, {2})'...".format( self.layout_func.__name__, self.square_frame.winfo_height(), self.square_frame.winfo_width())) self.layout_func(self.squares, self.square_frame.winfo_height(), self.square_frame.winfo_width())
file_name_label.config(fg="black") file_name_ = filedialog.askopenfilename(initialdir = getcwd(), title = "選取API金鑰", filetypes = (("json files","*.json"),("all files","*.*"))) file_name.set(file_name_) root = Tk() root.title(u"自動語音轉錄文字") root.geometry("300x240+200+200") root.resizable(False, False) lang_label = Label(text=u'選取語音語言') lang_label.config(font=("Courier", 12)) lang_label.place(x=30, y=20) lang_code = StringVar(root) lang_code.set(u"中文(繁體)") lang = OptionMenu(root, lang_code, *LANG_CODE_DICT.keys()) lang.config(font=("Courier", 12), width=8) lang.place(x=20, y=50) file_button = Button(text=u'選取API金鑰', command=choose_file) file_button.config(font=("Courier", 12)) file_button.place(x=24, y=110) file_name = StringVar() file_name.set('') file_name_label = Label(root, textvariable=file_name, justify=LEFT, wraplengt=250) file_name_label.place(x=20, y=150) connect_int = IntVar() connect_check = Checkbutton(root, text=u"連接至unity\n(5067號埠)",
class scRNASeqFrame(PipelineFrame): def __init__(self, pipepanel, pipeline_name, *args, **kwargs): PipelineFrame.__init__(self, pipepanel, pipeline_name, *args, **kwargs) self.info = None eframe = self.eframe = LabelFrame(self, text="Options") #,fg=textLightColor,bg=baseColor) eframe.grid(row=5, column=1, sticky=W, columnspan=7, padx=10, pady=5) label = Label(eframe, text="Pipeline") #,fg=textLightColor,bg=baseColor) label.grid(row=3, column=0, sticky=W, padx=10, pady=5) PipelineLabels = [ "CellRanger", "Initial/QC", "Clustering", "Multi-Sample Clustering" ] Pipelines = [ "cellranger", "scrnaseqinit", "scrnaseqcluster", "scrnaseqmulticluster" ] self.label2pipeline = {k: v for k, v in zip(PipelineLabels, Pipelines)} PipelineLabel = self.PipelineLabel = StringVar() self.Pipeline = StringVar() PipelineLabel.set(PipelineLabels[0]) om = OptionMenu(eframe, PipelineLabel, *PipelineLabels, command=self.option_controller) om.config() #bg = widgetBgColor,fg=widgetFgColor) om["menu"].config() #bg = widgetBgColor,fg=widgetFgColor) #om.pack(side=LEFT,padx=20,pady=5) om.grid(row=3, column=1, sticky=W, padx=10, pady=5) self.crOpts = crOpts = LabelFrame(eframe, text="CellRanger Settings") self.scrCRID = scrCRID = StringVar() scrCRID.set("SPECIFY_PREFIX_HERE") self.scrExpected = scrExpected = StringVar() scrExpected.set("3000") scrcridL = Label(crOpts, text="CellRanger Sample ID: ") scrcridE = Entry(crOpts, bd=2, width=25, textvariable=scrCRID) scrcridL.grid(row=9, column=1, sticky=W, padx=10, pady=5) scrcridE.grid(row=9, column=2, sticky=W, padx=0, pady=5) screxpectedL = Label(crOpts, text="Expected number of cells: ") screxpectedE = Entry(crOpts, bd=2, width=8, textvariable=scrExpected) screxpectedL.grid(row=10, column=1, sticky=W, padx=10, pady=5) screxpectedE.grid(row=10, column=2, sticky=W, padx=0, pady=5) self.clusterOpts = clusterOpts = LabelFrame( eframe, text="Clustering and tSNE Options") self.scrPCs = scrPCs = StringVar() scrPCs.set("12") self.scrRes = scrRes = StringVar() scrRes.set("0.6") #scrPCs.trace('w', lambda a,b,c,x="scrPCs": makejson(x)) #Filter out genes < [5] read counts in < [2] samples scrpcsL = Label(clusterOpts, text="Include principal components 1 through ") scrpcsE = Entry(clusterOpts, bd=2, width=3, textvariable=scrPCs) scrresL = Label(clusterOpts, text="with clustering resolution: ") scrresE = Entry(clusterOpts, bd=2, width=3, textvariable=scrRes) scrpcsL.grid(row=9, column=1, sticky=W, padx=10, pady=5) scrpcsE.grid(row=9, column=2, sticky=W, padx=0, pady=5) scrresL.grid(row=9, column=3, sticky=W, padx=5, pady=5) scrresE.grid(row=9, column=4, sticky=W, padx=0, pady=5) #scrRes.trace('w', lambda a,b,c,x="scrPCs": makejson(x)) clusterOpts.grid(row=8, column=0, columnspan=4, sticky=W, padx=20, pady=10) self.multiclusterOpts = multiclusterOpts = LabelFrame( eframe, text="Multi-Sample Clustering and tSNE Options") scrccsL = Label(multiclusterOpts, text="Include canonical components 1 through ") scrccsE = Entry(multiclusterOpts, bd=2, width=3, textvariable=scrPCs) scrmcresL = Label(multiclusterOpts, text="with clustering resolution: ") scrmcresE = Entry(multiclusterOpts, bd=2, width=3, textvariable=scrRes) scrccsL.grid(row=9, column=1, sticky=W, padx=10, pady=5) scrccsE.grid(row=9, column=2, sticky=W, padx=0, pady=5) scrmcresL.grid(row=9, column=3, sticky=W, padx=5, pady=5) scrmcresE.grid(row=9, column=4, sticky=W, padx=0, pady=5) self.qcOpts = qcOpts = LabelFrame(eframe, text="Initial Settings") countL = Label(qcOpts, text="Counts/Matrix Dir:") countL.grid(row=9, column=1, sticky=W, padx=10, pady=5) countpath = StringVar() self.countpath = countpath count_entry = Entry( qcOpts, bd=2, width=50, #bg = entryBgColor, #fg = entryFgColor, textvariable=countpath, state='normal') count_entry.grid(row=9, column=2, columnspan=3) self.count_button = count_button = Button( qcOpts, text="Open Directory", command=self.set_count_directory) count_button.grid(row=9, column=5) self.mattype = mattype = StringVar() mattypeL = Label(qcOpts, text="Count matrix format: ") scrMatTypeDropdown = ["cellranger", "cellranger_raw", "zumi", "biorad"] mattype.set(scrMatTypeDropdown[0]) mattype_om = OptionMenu(qcOpts, mattype, *scrMatTypeDropdown) mattypeL.grid(row=10, column=1, sticky=W, padx=10, pady=5) mattype_om.grid(row=10, column=2, sticky=W, padx=0, pady=5) self.docycleregress = docycleregress = StringVar() docycleregressL = Label(qcOpts, text="Do cell cycle regression? ") scrCycleDropdown = ["TRUE", "FALSE"] docycleregress.set(scrCycleDropdown[0]) cycle_om = OptionMenu(qcOpts, docycleregress, *scrCycleDropdown) docycleregressL.grid(row=11, column=1, sticky=W, padx=10, pady=5) cycle_om.grid(row=11, column=2, sticky=W, padx=0, pady=5) usecycleregressL_c = Label(clusterOpts, text="Use cell cycle regressed data? ") docycleregress.set(scrCycleDropdown[0]) cycle_om_c = OptionMenu(clusterOpts, docycleregress, *scrCycleDropdown) usecycleregressL_c.grid(row=10, column=1, sticky=W, padx=10, pady=5) cycle_om_c.grid(row=10, column=2, sticky=W, padx=0, pady=5) usecycleregressL_mc = Label(multiclusterOpts, text="Use cell cycle regressed data? ") docycleregress.set(scrCycleDropdown[0]) cycle_om_mc = OptionMenu(multiclusterOpts, docycleregress, *scrCycleDropdown) usecycleregressL_mc.grid(row=10, column=1, sticky=W, padx=10, pady=5) cycle_om_mc.grid(row=10, column=2, sticky=W, padx=0, pady=5) groups_buttonL = Label(qcOpts, text="SAMPLE INFORMATION: ") groups_button = Button(qcOpts, text="Set Groups", command=self.popup_groups) groups_buttonL.grid(row=12, column=1, sticky=W, padx=10, pady=5) groups_button.grid(row=12, column=2, sticky=W, padx=0, pady=5) ##################### self.option_controller() def popup_groups(self): self.popup_window("Groups Information", "groups.tab") def popup_window(self, text, filename): top = Toplevel() info = LabelFrame(top, text=text) #"Group Information") info_text = Text( info, width=50, height=8, #bg=projectBgColor, #fg=projectFgColor, font=("nimbus mono bold", "11")) def savefunc(): self.writepaste(filename, info_text) def loadfunc(): self.readpaste(filename, info_text) info_save_button = Button(info, text="Save", command=savefunc) info_load_button = Button(info, text="Load", command=loadfunc) #self.pairs_load_button.pack( side=BOTTOM, padx=5, pady=5 ) #self.pairs_save_button.pack( side=BOTTOM, padx=5, pady=5 ) info_load_button.grid(row=5, column=5, padx=10, pady=5) info_save_button.grid(row=5, column=6, padx=10, pady=5) info_text.grid(row=1, rowspan=3, column=1, columnspan=7, padx=5, pady=5) info.grid(row=7, column=0, columnspan=6, sticky=W, padx=20, pady=10) top.focus_force() def set_count_directory(self): fname = askdirectory(initialdir=USER_HOME, title="Select Data Directory") self.countpath.set(fname) def option_controller(self, *args, **kwargs): PipelineFrame.option_controller(self) self.Pipeline.set(self.label2pipeline[self.PipelineLabel.get()]) print(self.Pipeline.get()) if self.Pipeline.get() == 'cellranger': self.clusterOpts.grid_forget() self.crOpts.grid(row=8, column=0, columnspan=6, sticky=W, padx=20, pady=10) self.qcOpts.grid_forget() self.multiclusterOpts.grid_forget() elif self.Pipeline.get() == 'scrnaseqcluster': self.clusterOpts.grid(row=8, column=0, columnspan=4, sticky=W, padx=20, pady=10) self.crOpts.grid_forget() self.qcOpts.grid_forget() self.multiclusterOpts.grid_forget() elif self.Pipeline.get() == 'scrnaseqinit': self.clusterOpts.grid_forget() self.crOpts.grid_forget() self.qcOpts.grid(row=8, column=0, columnspan=4, sticky=W, padx=20, pady=10) self.multiclusterOpts.grid_forget() elif self.Pipeline.get() == 'scrnaseqmulticluster': self.clusterOpts.grid_forget() self.crOpts.grid_forget() self.qcOpts.grid_forget() self.multiclusterOpts.grid(row=8, column=0, columnspan=4, sticky=W, padx=20, pady=10) def makejson_wrapper(self, *args, **kwargs): self.makejson(*args, **kwargs) def makejson(self, *args): ###################################################### FROM RNASEQ.PY, NOT SURE WHAT ALL THIS DOES #############################3 #print(args[0]) caller = args[0] #global PD #global UnitsBak #global RGbak D = dict() try: F = open(self.workpath.get() + "/samples", "r") f = F.read().split("\n") F.close() for line in f: L = line.split() a = L.pop(0) D[a] = L samples = D except: samples = {"na": "na"} D = dict() try: F = open(self.workpath.get() + "/pairs", "r") f = F.read().split() F.close() for i in range(0, len(f), 2): # a=f[i].split(".")[0] # b=f[i+1].split(".")[0] a = f[i] b = f[i + 1] D[a + "+" + b] = [a, b] pairs = D except: pairs = {"na": "na"} D = dict() try: F = open(self.workpath.get() + "/contrasts.tab", "r") # f=F.read().split('\n') # F.close() # D["rsamps"]=f[0].split() # D["rgroups"]=f[1].split() # D["rcontrasts"]=f[2].split() # D["rlabels"]=f[3].split() f = F.readlines() F.close() ## sampl=[] ## grp=[] cont = [] ## lbl=[] for x in f: if len(x.split()) == 2: cont.append(x.split()[0]) cont.append(x.split()[1]) D["rcontrasts"] = cont # contrasts["rcontrasts"]=cont contrasts = D except: contrasts = {"rcontrasts": "na"} ## contrasts={"rsamps":"na","rgroups":"na","rcontrasts":"na","rlabels":"na"} ##------ D = dict() try: F = open(self.workpath.get() + "/groups.tab", "r") f = F.readlines() F.close() sampl = [] grp = [] # cont=[] lbl = [] for x in f: # if len(x.split()) == 4 or len(x.split()) == 3: if len(x.split()) == 3: sampl.append(x.split()[0]) grp.append(x.split()[1]) lbl.append(x.split()[2]) D["rsamps"] = sampl D["rgroups"] = grp D["rlabels"] = lbl # D["rcontrasts"]="na" # contrasts=D groups = D except: # contrasts={"rsamps":"na","rgroups":"na","rcontrasts":"na","rlabels":"na"} groups = {"rsamps": "na", "rgroups": "na", "rlabels": "na"} ##------ D = dict() FT = filetype #.get() # p = Popen("ls "+workpath.get()+"/*."+FT, shell=True, stdin=PIPE, stdout=PIPE, stderr=DEVNULL, close_fds=True) p = Popen("find " + self.workpath.get() + " -maxdepth 1 -type l -printf '%f\n' ", shell=True, stdin=PIPE, stdout=PIPE, stderr=DEVNULL, close_fds=True) a = p.stdout.read().decode(encoding='UTF-8').split("\n") RG = dict() b = a.pop() # tkinter.messagebox.showerror("",a) # if freezeunits.get()=="no": for i in a: key = re.sub(".realign", "", i.split("/")[-1]) key = re.sub(".bai", "", key) key = re.sub(".bam", "", key) key = re.sub(".sam", "", key) key = re.sub(".recal", "", key) key = re.sub(".dedup", "", key) key = re.sub(".sorted", "", key) key = re.sub(".fin", "", key) key = re.sub("\.R[12]", "", key) key = re.sub("_R[12]", "", key) key = re.sub(".fastq", "", key) key = re.sub(".gz", "", key) # key=re.sub("[\._](R[12]\.)*"+FT+"$","",i.split("/")[-1]) # key=re.sub(".R[12]."+FT+"$","",i.split("/")[-1]) # key=re.sub("([._]R[12][._])*([fin|sorted|dedup|recal|realign])*\.{0}$".format(FT),"",i.split("/")[-1]) D[key] = key RG[key] = { 'rgsm': key, 'rglb': 'na', 'rgpu': 'na', 'rgpl': 'ILLUMINA', 'rgcn': 'na' } units = D UnitsBak = D try: F = open(self.workpath.get() + "/rg.tab", "r") f = F.read().splitlines() F.close() for theLine in f: if not re.match("^ID", theLine): (rgid, rgsm, rglb, rgpl, rgpu, rgcn) = theLine.split("\t") RG[rgid] = { 'rgsm': rgsm, 'rglb': rglb, 'rgpu': rgpu, 'rgpl': rgpl, 'rgcn': rgcn } except: pass RGbak = RG # else: # units=UnitsBak # RG=RGbak # ########################################################################################################################### PD = dict() smparams = [] for i in range(len(self.parameters)): if cp[i].var.get() == "1": smparams.append(parameters[i]) AD = eval( open(join(PIPELINER_HOME, self.annotation.get() + ".json"), "r").read()) gi = self.global_info PD = { 'project': { 'pfamily': gi.pfamily.get(), 'units': units, 'samples': samples, 'pairs': pairs, 'id': gi.eprojectid.get(), 'pi': gi.epi.get(), 'organism': gi.eorganism.get(), 'analyst': gi.eanalyst.get(), 'poc': gi.epoc.get(), 'pipeline': self.Pipeline.get(), 'version': "4.0", 'annotation': gi.annotation.get(), 'datapath': self.datapath.get(), 'targetspath': self.targetspath.get(), 'filetype': filetype, 'binset': "standard-bin", 'username': gi.euser.get(), 'flowcellid': gi.eflowcell.get(), 'platform': gi.eplatform.get(), 'custom': customRules, 'efiletype': efiletype, 'workpath': self.workpath.get(), 'batchsize': batchsize, "smparams": smparams, "rgid": RG, "cluster": "cluster_medium.json", "description": gi.description.get('1.0', END), "technique": gi.technique.get(), "CRID": self.scrCRID.get(), "EXPECTED": self.scrExpected.get(), "COUNTSPATH": self.countpath.get(), "MATTYPE": self.mattype.get(), "DOCYCLEREGRESS": self.docycleregress.get(), "RESOLUTION": self.scrRes.get(), "PCS": self.scrPCs.get(), "groups": groups } } J = json.dumps(PD, sort_keys=True, indent=4, ensure_ascii=True) gi.jsonconf.delete("1.0", END) gi.jsonconf.insert(INSERT, J) self.saveproject(gi.jsonconf.get("1.0", END))
class Roller(Frame): def __init__(self, group, index): Frame.__init__(self, group) self.group = group self.index = index self.results = [0] self.history = [] self.name = StringVar() self.dice_qty = IntVar() self.die_faces = IntVar() self.modifier = IntVar() self.finalmod = IntVar() self.results_text = StringVar() self.name.trace('w', self.group.mainframe.set_unsaved_title) self.dice_qty.trace('w', self.group.mainframe.set_unsaved_title) self.die_faces.trace('w', self.group.mainframe.set_unsaved_title) self.modifier.trace('w', self.group.mainframe.set_unsaved_title) self.finalmod.trace('w', self.group.mainframe.set_unsaved_title) self.results_text.trace('w', self.group.mainframe.set_unsaved_title) default_font = ('Courier', 14) self.menu_btn = Menubutton(self, bd=1, relief='solid', font=('Courier', 8), text='\u25e2', takefocus=1, highlightthickness=1) self.name_entry = Entry(self, bd=1, relief='solid', font=('Verdana', 12), width=16, textvariable=self.name) self.dice_qty_spin = NumericSpinner(self, self.dice_qty, 1, 99, callback=self.reset, initial=1) self.die_faces_spin = NumericSpinner( self, self.die_faces, 2, 100, interval=self.group.mainframe.allow_odd.get(), initial=10) self.modifier_spin = NumericSpinner(self, self.modifier, -99, 100, callback=self.apply_modifiers) self.finalmod_spin = NumericSpinner(self, self.finalmod, -99, 100, callback=self.apply_modifiers) self.dice_lbl = Label(self, text=' d', font=default_font) self.modifier_lbl = Label(self, text='\u002b', font=default_font) self.finalmod_lbl = Label(self, text='\u002b', font=default_font) self.roll_btn = Button(self, bd=0, image=self.group.roll_img, command=lambda: self.roll(single=True)) self.results_entry = Entry(self, bd=0, relief='solid', font=default_font, width=0, textvariable=self.results_text, state='readonly', justify='center') self.menu_btn.config(menu=self.create_menu()) self.menu_btn.grid(row=index, column=0, padx=(4, 0)) self.name_entry.grid(row=index, column=1, padx=(4, 0)) self.dice_qty_spin.grid(row=index, column=2, padx=(4, 0)) self.dice_lbl.grid(row=index, column=3, padx=(0, 0)) self.die_faces_spin.grid(row=index, column=4, padx=(0, 0)) self.modifier_lbl.grid(row=index, column=5, padx=(6, 6)) self.modifier_spin.grid(row=index, column=6, padx=(0, 0)) self.roll_btn.grid(row=index, column=7, padx=(8, 0)) self.results_entry.grid(row=index, column=8, padx=(8, 0)) self.finalmod_lbl.grid(row=index, column=9, padx=(6, 6)) self.finalmod_spin.grid(row=index, column=10, padx=(0, 4)) self.name.set('Roller {}'.format(len(self.group.rollers) + 1)) self.die_faces.set(10) self.results_text.set('0 = 0') self.grid(row=index, sticky='w', pady=4) def create_menu(self): menu = Menu(self.menu_btn, tearoff=0, postcommand=self.group.maintain_roller_indices) menu.add_command(label='Add', underline=0, command=self.add_roller) menu.add_command(label='Clone', underline=0, command=lambda: self.add_roller(clone=True)) menu.add_command(label='Up', underline=0, command=lambda: self.move_roller(offset=-1)) menu.add_command(label='Down', underline=0, command=lambda: self.move_roller(offset=1)) menu.add_separator() # ------ menu.add_command(label='Remove', underline=0, command=self.remove_roller) return menu def create_hist_record(self): record = { 'dice_qty': self.dice_qty.get(), 'die_faces': self.die_faces.get(), 'modifier': self.modifier.get(), 'results_text': self.results_text.get(), 'finalmod': self.finalmod.get(), 'timestamp': str(dt.now().time())[:8], 'results': self.results } return record def add_roller(self, clone=False): destination_index = self.index + 1 roller = Roller(self.group, destination_index) self.group.rollers.insert(roller.index, roller) for i in range(destination_index, len(self.group.rollers)): self.group.rollers[i].grid(row=i + 1) if clone: roller.name.set(self.name.get()) roller.dice_qty.set(self.dice_qty.get()) roller.die_faces.set(self.die_faces.get()) roller.modifier.set(self.modifier.get()) roller.finalmod.set(self.finalmod.get()) roller.reset() for h in self.history: record = roller.create_hist_record() record['timestamp'] = h['timestamp'] roller.history.append(record) roller.apply_modifiers() for r in self.group.rollers: r.lift() self.group.mainframe.editmenu.entryconfigure( self.group.mainframe.editmenu.index('end'), command=lambda: self.add_roller(clone=clone)) self.group.mainframe.bind_all('<Control-r>', lambda e: self.add_roller(clone=clone)) def move_roller(self, offset=0, destination_index=0): if not destination_index: destination_index = self.index + offset if destination_index >= 0: roller = self.group.rollers.pop(self.index) self.group.rollers.insert(destination_index, roller) self.group.maintain_roller_indices() self.name.set(self.name.get()) self.group.mainframe.editmenu.entryconfigure( self.group.mainframe.editmenu.index('end'), command=lambda: self.move_roller(offset=offset)) self.group.mainframe.bind_all( '<Control-r>', lambda e: self.move_roller(offset=offset)) def remove_roller(self): if len(self.group.rollers) > 1: self.grid_remove() self.group.rollers.remove(self) self.name.set('') def reset(self, loading=False): self.results = [0 for i in range(self.dice_qty.get())] self.dice_qty_spin.step(0) self.die_faces_spin.step(0) self.modifier_spin.step(0) self.finalmod_spin.step(0) if not loading: self.apply_modifiers() self.group.maintain_result_widths() def roll(self, single=False): rolls = self.dice_qty.get() sides = self.die_faces.get() if self.group.mainframe.allow_odd.get() % 2 == 0 and sides % 2 != 0: self.die_faces.set(sides - 1) sides -= 1 mod = self.modifier.get() fmod = self.finalmod.get() max_roll = sides min_roll = 1 results = [] if self.group.mainframe.use_random_org.get(): url = 'https://www.random.org/integers/?col={0}&num={0}&min={1}&max={2}&base=10&format=plain&rnd=new' url = url.format(rolls, min_roll, max_roll) try: resp = urlopen(url) results.extend([ int(x) for x in str(resp.read().rstrip(), encoding='utf8').split('\t') ]) sleep(0.1) except: print('Failed to use random.org, falling back to CSPRNG!') if not results: csprng = SystemRandom() for i in range(rolls): roll = csprng.randint(min_roll, sides) results.append(roll) self.results = [] for n in results: if n == max_roll: self.results.append(n * CRIT) elif n == min_roll: self.results.append(n * FAIL) else: self.results.append(n) self.apply_modifiers(True) self.history.append(self.create_hist_record()) hist_index = len(self.history) - 1 if single: for roller in self.group.rollers: if roller is not self: roller.history.append(roller.create_hist_record()) self.group.navigate_history(desired_index=hist_index) self.group.hist_index = hist_index self.name.set(self.name.get()) self.group.mainframe.editmenu.entryconfigure( self.group.mainframe.editmenu.index('end'), command=lambda: self.roll(single=single)) self.group.mainframe.bind_all('<Control-r>', lambda e: self.roll(single=single)) def apply_modifiers(self, rolling=False): fmod = self.finalmod.get() dmod = self.modifier.get() dqty = self.dice_qty.get() formatted_results = [] total = 0 for n in self.results: if n > CRIT: n = int(n / CRIT) n = n + dmod formatted_results.append('\u25b2{}'.format(str(n))) elif 0 < n < 1: n = int(n / FAIL) n = n + dmod formatted_results.append('\u25bc{}'.format(str(n))) else: n = n + dmod formatted_results.append(str(n)) total += n s = ' + '.join(formatted_results) s = '{} = {}'.format(total + fmod, s) if not rolling and self.history: self.history[self.group.hist_index]['modifier'] = dmod self.history[self.group.hist_index]['finalmod'] = fmod self.history[self.group.hist_index]['results_text'] = s self.results_text.set(s) self.group.maintain_result_widths()
class RollerGroup(LabelFrame): def __init__(self, mainframe, index): LabelFrame.__init__(self, mainframe) self.mainframe = mainframe self.index = index self.hist_index = 0 self.collapsed = False self.rollers = [] self.control_frame = Frame(None) default_font = ('Verdana', 10) self.name = StringVar() self.name.trace('w', self.mainframe.set_unsaved_title) self.expand_img = PhotoImage( data= b'R0lGODlhEAAQAIABAAAAAP///yH5BAEKAAEALAAAAAAQABAAAAIlhI+pq+EPHYo0TGjifRkfDYAdI33WUnZc6KmlyK5wNdMrg+dJAQA7' ) self.collapse_img = PhotoImage( data= b'R0lGODlhEAAQAIABAAAAAP///yH5BAEKAAEALAAAAAAQABAAAAIfhI+pq+EPHYo0zAovlme/y3CGmJCeeWqbirEVA8dLAQA7' ) self.collapse_btn = Button(self.control_frame, bd=0, image=self.collapse_img, command=self.show_hide) self.menu_btn = Menubutton(self.control_frame, bd=1, relief='solid', font=('Courier', 8), text='\u25e2', takefocus=1, highlightthickness=1) self.name_entry = Entry(self.control_frame, bd=1, relief='solid', font=('Verdana', 12), width=16, textvariable=self.name) self.history_frame = LabelFrame(self.control_frame, bd=1, text='History', relief='solid', font=default_font, labelanchor='w') self.roll_frame = LabelFrame(self.control_frame, bd=1, text='Roll', relief='solid', font=default_font, labelanchor='w') self.roll_img = PhotoImage( data= b'R0lGODlhDgARAIABAAAAAP///yH5BAEKAAEALAAAAAAOABEAAAIkjB+Ai6C83GOy0iqjM7ltPoFhKEKeKZJadynfVa6HlbAp3ZIFADs=' ) self.left_arrow = PhotoImage( data= b'R0lGODlhBwANAIABAAAAAP///yH5BAEKAAEALAAAAAAHAA0AAAITjA9nkMj+Apty2lvt0jt2VYFSAQA7' ) self.right_arrow = PhotoImage( data= b'R0lGODlhBwANAIABAAAAAP///yH5BAEKAAEALAAAAAAHAA0AAAITRI5gGLrnXlzT1NsidEkx/zFHAQA7' ) self.roll_btn = Button(self.roll_frame, bd=0, image=self.roll_img, height=24, command=self.roll_group) self.hist_prev_btn = Button( self.history_frame, bd=0, image=self.left_arrow, height=24, width=16, repeatdelay=250, repeatinterval=100, command=lambda: self.navigate_history(offset=-1)) self.hist_next_btn = Button( self.history_frame, bd=0, image=self.right_arrow, height=24, width=16, repeatdelay=250, repeatinterval=100, command=lambda: self.navigate_history(offset=1)) self.menu_btn.config(menu=self.create_menu()) self.collapse_btn.grid(row=0, column=0, padx=(4, 0)) self.menu_btn.grid(row=0, column=1, padx=(4, 0)) self.name_entry.grid(row=0, column=2, padx=(4, 0)) self.history_frame.grid(row=0, column=3, padx=(6, 0)) self.hist_prev_btn.grid(row=0, column=0, padx=(6, 0)) self.hist_next_btn.grid(row=0, column=1, padx=(0, 2)) self.roll_frame.grid(row=0, column=4, padx=(6, 4)) self.roll_btn.grid(row=0, column=0, padx=(6, 2)) self.config(relief='solid', labelwidget=self.control_frame) self.name.set('Group {}'.format(len(roller_groups) + 1)) self.grid(row=index, padx=4, pady=4, sticky='w') def show_hide(self): if self.collapsed: for roller in self.rollers: roller.grid() self.collapse_btn.config(image=self.collapse_img) self.collapsed = False else: for roller in self.rollers: roller.grid_remove() self.collapse_btn.config(image=self.expand_img) width = 28 + self.collapse_btn.winfo_width( ) + self.menu_btn.winfo_width() + self.name_entry.winfo_width() self.config(height=36, width=width) self.collapsed = True def create_menu(self): menu = Menu(self.menu_btn, tearoff=0, postcommand=maintain_group_indices) menu.add_command(label='Add', underline=0, command=self.add_group) menu.add_command(label='Clone', underline=0, command=lambda: self.add_group(clone=True)) menu.add_command(label='Up', underline=0, command=lambda: self.move_group(offset=-1)) menu.add_command(label='Down', underline=0, command=lambda: self.move_group(offset=1)) menu.add_separator() # ------------- menu.add_command(label='Clear history', underline=6, command=self.clear_history) menu.add_command(label='Remove', underline=0, command=self.remove_group) return menu def add_group(self, clone=False): destination_index = self.index + 1 group = RollerGroup(self.mainframe, destination_index) roller_groups.insert(group.index, group) for i in range(destination_index, len(roller_groups)): roller_groups[i].grid(row=i + 1) if clone: for roller in self.rollers: new_roller = Roller(group, self.rollers.index(roller)) new_roller.name.set(roller.name.get()) new_roller.dice_qty.set(roller.dice_qty.get()) new_roller.die_faces.set(roller.die_faces.get()) new_roller.modifier.set(roller.modifier.get()) new_roller.finalmod.set(roller.finalmod.get()) group.rollers.append(new_roller) group.name.set(self.name.get()) else: group.rollers.append(Roller(group, 0)) group.name.set(group.name.get()) maintain_tabstops() self.mainframe.editmenu.entryconfigure( self.mainframe.editmenu.index('end'), command=lambda: self.add_group(clone=clone)) self.mainframe.bind_all('<Control-r>', lambda e: self.add_group(clone=clone)) def move_group(self, offset=0, destination_index=0): if not destination_index: destination_index = self.index + offset if destination_index >= 0: group = roller_groups.pop(self.index) roller_groups.insert(destination_index, group) maintain_group_indices() self.name.set(self.name.get()) self.mainframe.editmenu.entryconfigure( self.mainframe.editmenu.index('end'), command=lambda: self.move_group(offset=offset)) self.mainframe.bind_all('<Control-r>', lambda e: self.move_group(offset=offset)) def clear_history(self): for roller in self.rollers: roller.reset() roller.history = [] self.history_frame.config(text='History') def remove_group(self, override=False): if len(roller_groups) > 1 or override: self.grid_remove() roller_groups.remove(self) self.name.set('') def maintain_roller_indices(self): for roller in self.rollers: roller.index = self.rollers.index(roller) roller.grid(row=roller.index) def roll_group(self): for roller in self.rollers: roller.roll() self.navigate_history() self.mainframe.editmenu.entryconfigure( self.mainframe.editmenu.index('end'), command=lambda: self.roll_group()) self.mainframe.bind_all('<Control-r>', lambda e: self.roll_group()) def navigate_history(self, offset=0, desired_index=0): hist_len = len(self.rollers[0].history) if not hist_len: return if not desired_index: desired_index = self.hist_index + offset if desired_index >= -1 and desired_index <= hist_len: if desired_index == -1: desired_index = 0 if desired_index == hist_len: desired_index = hist_len - 1 for roller in self.rollers: hist_dict = roller.history[desired_index] roller.results = hist_dict['results'] roller.dice_qty.set(hist_dict['dice_qty']) roller.die_faces.set(hist_dict['die_faces']) roller.modifier.set(hist_dict['modifier']) roller.results_text.set(hist_dict['results_text']) roller.finalmod.set(hist_dict['finalmod']) self.history_frame.config(text=hist_dict['timestamp']) self.hist_index = desired_index self.maintain_result_widths() def maintain_result_widths(self): for roller in self.rollers: w = len(roller.results_text.get()) if w > 80: w = 80 roller.results_entry.config(width=w)
class Launcher: def __init__(self, root, app, appOptions): self.title_prefix = "SUMO Application launcher" self.root = root self.appVar = StringVar() self.appVar.set(app) self.appOptions = appOptions self.optionValues = {} self.root.title(self.title_prefix) self.root.minsize(700, 200) self.root.geometry("700x400") #self.root.iconphoto(True, PhotoImage(file = os.path.join(THISDIR, "launcher.gif"))) numButtons = self.mainButtons() for i in range(numButtons): root.columnconfigure(i, weight=1) root.rowconfigure(0, weight=10) root.rowconfigure(1, weight=1) sFrame = ScrollableFrame(root) sFrame.grid(row=1, column="0", columnspan=numButtons, sticky="NSEW") self.optFrame = sFrame.frame self.buildAppOptions(appOptions) # define options for opening or saving a file self.file_opt = options = {} self.filedir = os.getcwd() options['defaultextension'] = 'cfg' options['filetypes'] = [('all files', '.*')] options['initialdir'] = self.filedir options['parent'] = root def buildAppOptions(self, appOptions): NAME, VALUE, HELP = range(3) row = 0 for o in appOptions: row += 1 Label(self.optFrame, text=o.name).grid( row=row, column=NAME, sticky="NW") widget, var = buildValueWidget(self.optFrame, o.type) self.optionValues[o.name] = var widget.grid(row=row, column=VALUE, sticky="NW") Label(self.optFrame, text=o.help, justify=LEFT).grid( row=row, column=HELP, sticky="NW") def mainButtons(self): row = 0 col = 0 self.buttons = [] mb = Menubutton(self.root, text="Select Application") mb.menu = Menu(mb, tearoff=0) mb["menu"] = mb.menu for app in APPLICATIONS: mb.menu.add_radiobutton(label=app, variable=self.appVar, command=self.onSelectApp) mb.grid(row=row, column=col, sticky="NEW") col += 1 self.buttons.append(mb) otherButtons = ( ("Run %12s" % self.appVar.get(), self.runApp), ("load Config", self.loadCfg), ("Save Config", self.saveCfg), ("Save Config as", self.saveCfgAs), ("Quit", self.root.quit), ) for text, command in otherButtons: self.buttons.append(Button(self.root, text=text, command=command)) self.buttons[-1].grid(row=row, column=col, sticky="NEW") col += 1 return len(self.buttons) def onSelectApp(self): self.buttons[1].configure(text="Run %12s" % self.appVar.get()) def runApp(self): subprocess.call(os.path.join(BINDIR, self.appVar.get())) def loadCfg(self): self.file_opt['title'] = 'Load configuration file' filename = filedialog.askopenfilename(**self.file_opt) self.root.title(self.title_prefix + " " + filename) self.loadedOptions = readOptions(filename) for o in self.loadedOptions: self.optionValues[o.name].set(o.value) def saveCfg(self): pass def saveCfgAs(self): pass
class SatelliteWindow(Toplevel): """ SatelliteWindow is used to display nosetests results of concurrently run python interpreters. """ def cleanupOnQuit(self): """When closing popup, do a little clean up.""" # I'm not sure that transient windows need this, but I'm trying to be careful self.MainWin.focus_set() if self.main_gui.kill_popup_window(self.statusMessage.get()): self.destroy() self.main_gui.statusMessage.set('Closed: ' + self.statusMessage.get()) else: self.main_gui.statusMessage.set('ERROR Closing: ' + self.statusMessage.get()) self.main_gui.set_statusbar_bg('#FF9999') def __init__(self, main_gui, MainWin, mytitle, dx=30, dy=30): """Initialize popup""" Toplevel.__init__(self, MainWin) self.title(mytitle) x = MainWin.winfo_x() if x < 10: x = 10 y = MainWin.winfo_y() if y < 10: y = 10 # position over to the upper right self.geometry('+%i+%i' % (x + dx, y + dy)) self.config(highlightcolor='#FF99FF', highlightbackground='#FF99FF', highlightthickness=2, borderwidth=10) #=========== # make a Status Bar self.statusMessage = StringVar() self.statusMessage.set(mytitle) self.statusbar = Label(self, textvariable=self.statusMessage, bd=1, relief=SUNKEN) self.statusbar.pack(anchor=SW, fill=X, side=BOTTOM) self.statusbar_bg = self.statusbar.cget('bg') # save bg for restore myFont = tkinter.font.Font(family="Arial", size=12, weight=tkinter.font.BOLD) self.statusbar.config(font=myFont) frame = Frame(self) frame.pack(anchor=NE, fill=BOTH, side=TOP) self.Pass_Fail_Button = Button(frame, text="Pass/Fail Will Be Shown Here", image="", width="15", background="green", anchor=W, justify=LEFT, padx=2) self.Pass_Fail_Button.pack(anchor=NE, fill=X, side=TOP) self.Pass_Fail_Button.bind("<ButtonRelease-1>", self.Pass_Fail_Button_Click) #self.title('%s %s.%s.%s '%(python_exe_name, python_major, python_minor, python_micro)) self.oscillator = 1 # animates character on title self.oscillator_B = 0 # used to return statusbar to statusbar_bg self.lbframe = Frame(frame) self.lbframe.pack(anchor=SE, side=LEFT, fill=BOTH, expand=1) scrollbar = Scrollbar(self.lbframe, orient=VERTICAL) self.Text_1 = Text(self.lbframe, width="80", height="24", yscrollcommand=scrollbar.set) scrollbar.config(command=self.Text_1.yview) scrollbar.pack(side=RIGHT, fill=Y) self.Text_1.pack(side=LEFT, fill=BOTH, expand=1) self.resizable(1, 1) # Linux may not respect this #=========== self.MainWin = MainWin self.main_gui = main_gui # only main window can close this window self.protocol('WM_DELETE_WINDOW', self.cleanupOnQuit) def Pass_Fail_Button_Click(self, event): """Place-holder routine for user clicking Pass/Fail Button""" self.main_gui.Pass_Fail_Button_Click(event) def reset_statusbar_bg(self): """Return status bar to default state""" self.statusbar.config(bg=self.statusbar_bg) def set_statusbar_bg(self, c): """Set status bar to show new color and message""" self.statusbar.config(bg=c) self.oscillator_B = 1 # will return to initial color after a few cycles
class DescrPanel(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller # self.config_dl = commen_component.load_config_dl() self.var_link = StringVar() self.button_get_descr = Button(self, text="一键获取简介", command=self.get_descr) self.entry_link = tk.Entry(self, textvariable=self.var_link, width=80, borderwidth=3, font=('Helvetica', '10')) self.entry_link.bind('<Return>', self.enter_click) self.txtContent = tkinter.scrolledtext.ScrolledText(self, height=23, font=("Helvetica", 10), wrap=tkinter.WORD) self.btn_clear = Button(self, text="清空", command=self.clear_descr) self.label_remind = Label(self, text='温馨提示:链接包括原始站点链接,或者IMDB/豆瓣链接', fg='red', anchor=W) self.label_link = Label(self, text='链接', font=("Helvetica", 10), anchor=W) self.create_page() def create_page(self): self.label_link.place(x=30, y=20, width=50, height=30) self.entry_link.place(x=80, y=20, width=620, height=30) self.button_get_descr.place(x=30, y=65, width=120, height=30) self.btn_clear.place(x=170, y=65, width=60, height=30) self.label_remind.place(x=280, y=65, width=570, height=30) self.txtContent.place(x=32, y=110, width=680, height=450) def get_descr(self): # 获取链接 url = self.var_link.get() link_type, url_for_descr = self.__judge_link_type(url) if link_type == 'douban_imdb': try: descr = get_douban_info.get_douban_descr(url_for_descr) except Exception as exc: tk.messagebox.showerror('错误', '获取豆瓣信息出错:%s' % exc) elif link_type == 'detail_link': origin_site = common_methods.find_origin_site(url_for_descr) if origin_site['abbr'] == 'FRDS': html = common_methods.get_response_by_firefox(url_for_descr) else: response = common_methods.get_response(url_for_descr, origin_site['cookie']) html = response.text try: htmlhandler = html_handler.HtmlHandler(origin_site['abbr'], html) raw_info_tmp = htmlhandler.get_raw_info() descr = raw_info_tmp['descr'] except Exception as exc: tk.messagebox.showerror('Error', '从源链接获取简介错误:%s' % exc) else: descr = '' self.txtContent.insert(tkinter.INSERT, descr) def enter_click(self, event): self.get_descr() def __judge_link_type(self, url): url = self.var_link.get() if not url: return '', '' douban_link = get_douban_info.get_douban_link(url) if not douban_link: support_sign = common_methods.find_origin_site(url) if not support_sign: tk.messagebox.showerror('Error', '错误的链接!') return '', '' else: torrent_id = common_methods.get_id(url) if torrent_id == -1: tk.messagebox.showerror('Error', '错误的链接!错误的链接!') return '', '' else: return 'detail_link', url else: return 'douban_imdb', douban_link def clear_descr(self): self.var_link.set('') self.txtContent.delete(0.0, tk.END)
class GrepDialog(SearchDialogBase): "Dialog for searching multiple files." title = "Find in Files Dialog" icon = "Grep" needwrapbutton = 0 def __init__(self, root, engine, flist): """Create search dialog for searching for a phrase in the file system. Uses SearchDialogBase as the basis for the GUI and a searchengine instance to prepare the search. Attributes: globvar: Value of Text Entry widget for path to search. recvar: Boolean value of Checkbutton widget for traversing through subdirectories. """ SearchDialogBase.__init__(self, root, engine) self.flist = flist self.globvar = StringVar(root) self.recvar = BooleanVar(root) def open(self, text, searchphrase, io=None): "Make dialog visible on top of others and ready to use." SearchDialogBase.open(self, text, searchphrase) if io: path = io.filename or "" else: path = "" dir, base = os.path.split(path) head, tail = os.path.splitext(base) if not tail: tail = ".py" self.globvar.set(os.path.join(dir, "*" + tail)) def create_entries(self): "Create base entry widgets and add widget for search path." SearchDialogBase.create_entries(self) self.globent = self.make_entry("In files:", self.globvar)[0] def create_other_buttons(self): "Add check button to recurse down subdirectories." btn = Checkbutton( self.make_frame()[0], variable=self.recvar, text="Recurse down subdirectories") btn.pack(side="top", fill="both") def create_command_buttons(self): "Create base command buttons and add button for search." SearchDialogBase.create_command_buttons(self) self.make_button("Search Files", self.default_command, 1) def default_command(self, event=None): """Grep for search pattern in file path. The default command is bound to <Return>. If entry values are populated, set OutputWindow as stdout and perform search. The search dialog is closed automatically when the search begins. """ prog = self.engine.getprog() if not prog: return path = self.globvar.get() if not path: self.top.bell() return from idlelib.outwin import OutputWindow # leave here! save = sys.stdout try: sys.stdout = OutputWindow(self.flist) self.grep_it(prog, path) finally: sys.stdout = save def grep_it(self, prog, path): """Search for prog within the lines of the files in path. For the each file in the path directory, open the file and search each line for the matching pattern. If the pattern is found, write the file and line information to stdout (which is an OutputWindow). """ dir, base = os.path.split(path) list = self.findfiles(dir, base, self.recvar.get()) list.sort() self.close() pat = self.engine.getpat() print(f"Searching {pat!r} in {path} ...") hits = 0 try: for fn in list: try: with open(fn, errors='replace') as f: for lineno, line in enumerate(f, 1): if line[-1:] == '\n': line = line[:-1] if prog.search(line): sys.stdout.write(f"{fn}: {lineno}: {line}\n") hits += 1 except OSError as msg: print(msg) print(f"Hits found: {hits}\n(Hint: right-click to open locations.)" if hits else "No hits.") except AttributeError: # Tk window has been closed, OutputWindow.text = None, # so in OW.write, OW.text.insert fails. pass def findfiles(self, dir, base, rec): """Return list of files in the dir that match the base pattern. If rec is True, recursively iterate through subdirectories. """ try: names = os.listdir(dir or os.curdir) except OSError as msg: print(msg) return [] list = [] subdirs = [] for name in names: fn = os.path.join(dir, name) if os.path.isdir(fn): subdirs.append(fn) else: if fnmatch.fnmatch(name, base): list.append(fn) if rec: for subdir in subdirs: list.extend(self.findfiles(subdir, base, rec)) return list
def LengthConverter(): # factors to multiply to a value to convert from the following units to meters(m) factors = { 'nmi': 1852, 'mi': 1609.34, 'yd': 0.9144, 'ft': 0.3048, 'inch': 0.0254, 'km': 1000, 'm': 1, 'cm': 0.01, 'mm': 0.001 } ids = { "Nautical Miles": 'nmi', "Miles": 'mi', "Yards": 'yd', "Feet": 'ft', "Inches": 'inch', "Kilometers": 'km', "meters": 'm', "centimeters": 'cm', "millileters": 'mm' } # function to convert from a given unit to another def convert(amt, frm, to): if frm != 'm': amt = amt * factors[frm] return amt / factors[to] else: return amt / factors[to] def callback(): try: amt = float(in_field.get()) except ValueError: out_amt.set('Invalid input') return None if in_unit.get() == 'Select Unit' or out_unit.get() == 'Select Unit': out_amt.set('Input or output unit not chosen') return None else: frm = ids[in_unit.get()] to = ids[out_unit.get()] out_amt.set(convert(amt, frm, to)) # initiate window root = Toplevel() root.title("Length Converter") # initiate frame mainframe = ttk.Frame(root, padding="3 3 12 12") mainframe.pack(fill=BOTH, expand=1) titleLabel = Label(mainframe, text="Length Converter", font=("Arial", 12, "bold"), justify=CENTER).grid(column=1, row=1) in_amt = StringVar() in_amt.set('0') out_amt = StringVar() in_unit = StringVar() out_unit = StringVar() in_unit.set('Select Unit') out_unit.set('Select Unit') # Add input field in_field = ttk.Entry(mainframe, width=20, textvariable=in_amt) in_field.grid(row=1, column=2, sticky=(W, E)) # Add drop-down for input unit in_select = OptionMenu(mainframe, in_unit, "Nautical Miles", "Miles", "Yards", "Feet", "Inches", "Kilometers", "meters", "centimeters", "millileters").grid(column=3, row=1, sticky=W) # Add output field and drop-down ttk.Entry(mainframe, textvariable=out_amt, state="readonly").grid(column=2, row=3, sticky=(W, E)) in_select = OptionMenu(mainframe, out_unit, "Nautical Miles", "Miles", "Yards", "Feet", "Inches", "Kilometers", "meters", "centimeters", "millileters").grid(column=3, row=3, sticky=W) calc_button = ttk.Button(mainframe, text="Calculate", command=callback).grid(column=2, row=2, sticky=E) for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5) in_field.focus()
class FormularioArticulos: def __init__(self): self.articulo1=idleArticulos.Articulos() self.ventana1=tk.Tk() self.ventana1.title("Mantenimiento de artículos") self.cuaderno1 = ttk.Notebook(self.ventana1) self.carga_articulos() self.consulta_por_codigo() self.listado_completo() self.borrar_articulo() self.modificacion() self.cuaderno1.grid(column=0, row=0, padx=10, pady=10) self.ventana1.mainloop() def carga_articulos(self): self.pagina1 = ttk.Frame(self.cuaderno1) self.cuaderno1.add(self.pagina1, text="Carga de artículos") self.labelframe1=ttk.LabelFrame(self.pagina1, text="Artículo") self.labelframe1.grid(column=0, row=0, padx=5, pady=10) self.label1=ttk.Label(self.labelframe1, text="Descripción:") self.label1.grid(column=0, row=0, padx=4, pady=4) self.descripcioncarga=tk.StringVar() self.entrydescripcion=ttk.Entry(self.labelframe1, textvariable=self.descripcioncarga) self.entrydescripcion.grid(column=1, row=0, padx=4, pady=4) self.label2=ttk.Label(self.labelframe1, text="Precio:") self.label2.grid(column=0, row=1, padx=4, pady=4) self.preciocarga=tk.StringVar() self.entryprecio=ttk.Entry(self.labelframe1, textvariable=self.preciocarga) self.entryprecio.grid(column=1, row=1, padx=4, pady=4) self.boton1=ttk.Button(self.labelframe1, text="Confirmar", command=self.agregar) self.boton1.grid(column=1, row=2, padx=4, pady=4) def agregar(self): datos=(self.descripcioncarga.get(), self.preciocarga.get()) self.articulo1.alta(datos) mb.showinfo("Información", "Los datos fueron cargados") self.descripcioncarga.set("") self.preciocarga.set("") def consulta_por_codigo(self): self.pagina2 = ttk.Frame(self.cuaderno1) self.cuaderno1.add(self.pagina2, text="Consulta por código") self.labelframe2=ttk.LabelFrame(self.pagina2, text="Artículo") self.labelframe2.grid(column=0, row=0, padx=5, pady=10) self.label1=ttk.Label(self.labelframe2, text="Código:") self.label1.grid(column=0, row=0, padx=4, pady=4) self.codigo=tk.StringVar() self.entrycodigo=ttk.Entry(self.labelframe2, textvariable=self.codigo) self.entrycodigo.grid(column=1, row=0, padx=4, pady=4) self.label2=ttk.Label(self.labelframe2, text="Descripción:") self.label2.grid(column=0, row=1, padx=4, pady=4) self.descripcion=tk.StringVar() self.entrydescripcion=ttk.Entry(self.labelframe2, textvariable=self.descripcion, state="readonly") self.entrydescripcion.grid(column=1, row=1, padx=4, pady=4) self.label3=ttk.Label(self.labelframe2, text="Precio:") self.label3.grid(column=0, row=2, padx=4, pady=4) self.precio=tk.StringVar() self.entryprecio=ttk.Entry(self.labelframe2, textvariable=self.precio, state="readonly") self.entryprecio.grid(column=1, row=2, padx=4, pady=4) self.boton1=ttk.Button(self.labelframe2, text="Consultar", command=self.consultar) self.boton1.grid(column=1, row=3, padx=4, pady=4) def consultar(self): datos=(self.codigo.get(), ) respuesta=self.articulo1.consulta(datos) if len(respuesta)>0: self.descripcion.set(respuesta[0][0]) self.precio.set(respuesta[0][1]) else: self.descripcion.set('') self.precio.set('') mb.showinfo("Información", "No existe un artículo con dicho código") def listado_completo(self): self.pagina3 = ttk.Frame(self.cuaderno1) self.cuaderno1.add(self.pagina3, text="Listado completo") self.labelframe3=ttk.LabelFrame(self.pagina3, text="Artículo") self.labelframe3.grid(column=0, row=0, padx=5, pady=10) self.boton1=ttk.Button(self.labelframe3, text="Listado completo", command=self.listar) self.boton1.grid(column=0, row=0, padx=4, pady=4) self.scrolledtext1=st.ScrolledText(self.labelframe3, width=30, height=10) self.scrolledtext1.grid(column=0,row=1, padx=10, pady=10) def listar(self): respuesta=self.articulo1.recuperar_todos() self.scrolledtext1.delete("1.0", tk.END) for fila in respuesta: self.scrolledtext1.insert(tk.END, "código:"+str(fila[0])+"\ndescripción:"+fila[1]+"\nprecio:"+str(fila[2])+"\n\n") def borrar_articulo(self): self.pagina4=ttk.Frame(self.cuaderno1) self.cuaderno1.add(self.pagina4, text="Borrar articulo") self.labelframe4=ttk.Labelframe(self.pagina4, text="articulo") self.labelframe4.grid(column=0, row=0, padx=5, pady=5) self.label4=ttk.Label(self.labelframe4, text="Codigo del articulo:") self.label4.grid(column=0, row=0, padx=4, pady=4) self.dato=StringVar() self.entrydato=ttk.Entry(self.labelframe4, textvariable=self.dato) self.entrydato.grid(column=1, row=0, padx=4, pady=4) self.boton1=ttk.Button(self.labelframe4, text="Eliminar", command=self.eliminar) self.boton1.grid(column=1, row=1, padx=4, pady=5) def eliminar(self): codigo=(self.dato.get(), ) respuesta=self.articulo1.baja(codigo) if respuesta > 0: mb.showinfo("Informacion!", "El articulo ha sido eliminado") else: mb.showerror("Error!", "No existe ningun articulo con ese codigo") def modificacion(self): self.pagina5=ttk.Frame(self.cuaderno1) self.cuaderno1.add(self.pagina5, text="Modificacar articulo") self.labelframe5=ttk.Labelframe(self.pagina5, text="Articulo") self.labelframe5.grid(column=0, row=0, padx=5, pady=5) self.label5=ttk.Label(self.labelframe5, text="Codigo del articulo") self.label5.grid(column=0, row=0, padx=4, pady=4) self.dato_mod=StringVar() self.entry_mod=ttk.Entry(self.labelframe5, textvariable=self.dato_mod) self.entry_mod.grid(column=1, row=0, padx=4, pady=4) self.label6=ttk.Label(self.labelframe5, text="Descripcion:") self.label6.grid(column=0, row=1, padx=4, pady=4) self.descripcion_mod=StringVar() self.descripcion_mod_entry=ttk.Entry(self.labelframe5, textvariable=self.descripcion_mod) self.descripcion_mod_entry.grid(column=1, row=1, padx=4, pady=4) self.label7=ttk.Label(self.labelframe5, text="Precio:") self.label7.grid(column=0, row=2, padx=4, pady=4) self.precio_mod=tk.StringVar() self.precio_mod_entry=ttk.Entry(self.labelframe5, textvariable=self.precio_mod) self.precio_mod_entry.grid(column=1, row=2, padx=4, pady=4) self.boton2=ttk.Button(self.labelframe5, text="Consultar", command=self.consulta_mod) self.boton2.grid(column=1, row=3, padx=4, pady=4) self.boton3=ttk.Button(self.labelframe5, text="Modificar", command=self.editar) self.boton3.grid(column=1, row=4, padx=4, pady=4) def consulta_mod(self): codigo=(self.dato_mod.get(), ) respuesta=self.articulo1.consulta_mod(codigo) if len(respuesta) > 0: self.descripcion_mod.set(respuesta[0][0]) self.precio_mod.set(respuesta[0][1]) else: mb.showerror("Error!", "No existe ningun articulo con ese codigo") self.descripcion_mod.set("") self.precio_mod.set("") def editar(self): actualizacion=(self.descripcion_mod.get(), self.precio_mod.get(), self.dato_mod.get() ) respuesta=self.articulo1.modificacion(actualizacion) if respuesta > 0: mb.showinfo("Informacion", "EL articulo ha sido actualizado") else: mb.showerror("Error!", "No existe ningun articulo con ese codigo")
def CurrencyConverter(): ids = { "US Dollar": 'USD', "Euros": 'EUR', "Indian Rupees": 'INR', "Qatar Doha": 'QAR', "Zimbwabe Harare": 'ZWD', "Arab Emirates Dirham": 'AED', "Pound Sterling": 'GBP', "Japanese Yen": 'JPY', "Yuan Renminbi": 'CNY' } def convert(amt, frm, to): html = urllib.request.urlopen( "http://www.exchangerate-api.com/%s/%s/%f?k=a28d653d2d4fd2727003e437" % (frm, to, amt)) return html.read().decode('utf-8') def callback(): try: amt = float(in_field.get()) except ValueError: out_amt.set('Invalid input') return None if in_unit.get() == 'Select Unit' or out_unit.get() == 'Select Unit': out_amt.set('Input or output unit not chosen') return None else: frm = ids[in_unit.get()] to = ids[out_unit.get()] out_amt.set(convert(amt, frm, to)) root = Toplevel() root.title("Currency Converter") # initiate frame mainframe = ttk.Frame(root, padding="3 3 12 12") mainframe.pack(fill=BOTH, expand=1) titleLabel = Label(mainframe, text="Currency Converter", font=("Arial", 12, "bold"), justify=CENTER).grid(column=1, row=1) in_amt = StringVar() in_amt.set('0') out_amt = StringVar() in_unit = StringVar() out_unit = StringVar() in_unit.set('Select Unit') out_unit.set('Select Unit') # Add input field in_field = ttk.Entry(mainframe, width=20, textvariable=in_amt) in_field.grid(row=1, column=2, sticky=(W, E)) # Add drop-down for input unit in_select = OptionMenu(mainframe, in_unit, "US Dollar", "Euros", "Indian Rupees", "Qatar Doha", "Zimbwabe Harare", "Arab Emirates Dirham", "Pound Sterling", "Japanese Yen", "Yuan Renminbi").grid(column=3, row=1, sticky=W) # Add output field and drop-down ttk.Entry(mainframe, textvariable=out_amt, state="readonly").grid(column=2, row=3, sticky=(W, E)) in_select = OptionMenu(mainframe, out_unit, "US Dollar", "Euros", "Indian Rupees", "Qatar Doha", "Zimbwabe Harare", "Arab Emirates Dirham", "Pound Sterling", "Japanese Yen", "Yuan Renminbi").grid(column=3, row=3, sticky=W) calc_button = ttk.Button(mainframe, text="Calculate", command=callback).grid(column=2, row=2, sticky=E) for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5) in_field.focus()
class OptionsFrame(LabelFrame): ''' This class creates Checkbuttons and Radiobuttons for displaying and modifying some of the parameters. Attributes: params (Parameters): object with all parameters. Some of the parameter values are modified in this class. current_categories (list of str): list of categories. input_categories_frame (CategoriesCheckBox): frame with input categories. It is needed in this class to read what categories are input. output_categories_frame (CategoriesCheckBox): frame with output categories. It is needed in this class to read what categories are output. categorical_box (Combobox): Combobox for choosing categorical category. combobox_text_var (StringVar): text variable of categorical_box. options (dict of str to IntVar): dictionary that stores IntVars of Radiobuttons and Checkbuttons. Example: >>> options = {"RETURN_TO_SCALE": IntVar(), "ORIENTATION": IntVar()} multi_tol_strvar (StringVar): StringVar object that stores tolerance of multiplier model. max_slack_box (Checkbutton): Checkbutton for the option "Two phase". Args: parent (Tk object): parent of this widget. params (Parameters): object with all parameters. Some of the parameter values are modified in this class. current_categories (list of str): list of categories. input_categories_frame (CategoriesCheckBox): frame with input categories. It is needed in this class to read what categories are input. output_categories_frame (CategoriesCheckBox): frame with output categories. It is needed in this class to read what categories are output. name (str, optional): name of the LabelFrame that this class represents, defaults to Options. ''' def __init__(self, parent, params, current_categories, input_categories_frame, output_categories_frame, name='Options', *args, **kw): super().__init__(parent, text=name, *args, **kw) self.params = params self.current_categories = current_categories self.input_categories_frame = input_categories_frame self.output_categories_frame = output_categories_frame self.categorical_box = None self.combobox_text_var = StringVar() self.combobox_text_var.trace('w', self.on_categorical_box_change) self.options = dict() self.multi_tol_strvar = StringVar() self.multi_tol_strvar.trace('w', self.on_multi_tol_change) self.max_slack_box = None self.create_widgets() def create_widgets(self): ''' Creates all widgets. ''' rts_lbl = Label(self, text='Return to scale:') rts_lbl.grid(row=0, column=0, padx=XPAD_VALUE, pady=YPAD_VALUE, sticky=W) self._create_frame_with_radio_btns(self, 'RETURN_TO_SCALE', ['VRS', 'CRS'], row_index=1, column_index=0) orientation_lbl = Label(self, text='Orientation:') orientation_lbl.grid(row=0, column=1, sticky=W, padx=XPAD_VALUE, pady=YPAD_VALUE) self._create_frame_with_radio_btns(self, 'ORIENTATION', ['Input', 'Output'], row_index=1, column_index=1) model_lbl = Label(self, text='Model:') model_lbl.grid(row=0, column=2, padx=XPAD_VALUE, pady=YPAD_VALUE, sticky=W) self._create_frame_with_radio_btns(self, 'DEA_FORM', ['Envelopment', 'Multiplier'], row_index=1, column_index=2, add_both=False) other_lbl = Label(self, text='Others:') other_lbl.grid(row=0, column=3, sticky=W, padx=XPAD_VALUE) max_slacks = IntVar() self.options['MAXIMIZE_SLACKS'] = max_slacks frame_other_options = Frame(self) self.max_slack_box = max_slacks_check_btn = Checkbutton( frame_other_options, text='Two phase', variable=max_slacks, command=(lambda: self.on_check_box_click( max_slacks, 'MAXIMIZE_SLACKS'))) max_slacks_check_btn.grid(row=1, column=0, sticky=W) super_efficiency = IntVar() self.options['USE_SUPER_EFFICIENCY'] = super_efficiency super_efficiency_check_btn = Checkbutton(frame_other_options, text='Super efficiency', variable=super_efficiency, command=( lambda: self.on_check_box_click( super_efficiency, 'USE_SUPER_EFFICIENCY'))) super_efficiency_check_btn.grid(row=2, column=0, sticky=W) peel_the_onion = IntVar() self.options['PEEL_THE_ONION'] = peel_the_onion peel_the_onion_check_btn = Checkbutton( frame_other_options, text='Peel the onion', variable=peel_the_onion, command=(lambda: self.on_check_box_click(peel_the_onion, 'PEEL_THE_ONION'))) peel_the_onion_check_btn.grid(row=3, column=0, sticky=W) frame_other_options.grid(row=1, column=3, padx=XPAD_VALUE, pady=YPAD_VALUE, sticky=W) frame_for_toleramce = Frame(self) tolerance_lbl = Label(frame_for_toleramce, text='Multiplier model tolerance:') tolerance_lbl.grid(row=0, column=0, padx=XPAD_VALUE, pady=YPAD_VALUE, sticky=W) tolerance_ent = Entry(frame_for_toleramce, width=5, textvariable=self.multi_tol_strvar) tolerance_ent.insert(END, 0) tolerance_ent.grid(row=0, column=1, sticky=W, padx=XPAD_VALUE) categorical_lbl = Label(frame_for_toleramce, text='Categorical:') categorical_lbl.grid(row=1, column=0, padx=XPAD_VALUE, pady=YPAD_VALUE, sticky=W) self.categorical_box = categorical_box = Combobox( frame_for_toleramce, textvariable=self.combobox_text_var, exportselection=0, state="readonly", width=20, values=(''), postcommand=self.change_categorical_box) categorical_box.grid(row=1, column=1, padx=XPAD_VALUE, pady=YPAD_VALUE, sticky=W) frame_for_toleramce.grid(row=5, column=0, sticky=W, padx=XPAD_VALUE, pady=YPAD_VALUE, columnspan=4) def _create_frame_with_radio_btns(self, parent, name, text, row_index, column_index, add_both=True): ''' Creates frame with one set of Radiobuttons. Args: parent (Tk object): parent of the frame. name (str): name of the parameter that will a key in options dictionary. text (list of str): list with two parameter values that should be displayed next to the first two Radiobuttons. row_index (int): index of the row where the frame should be placed using grid method. column_index (int): index of the column where the frame should be placed using grid method. add_both (bool, optional): True if the third Radiobutton with text "both" must be displayed, False otherwise, defaults to True. ''' assert len(text) == 2 v = IntVar() self.options[name] = v self.options[name].trace( 'w', (lambda *args: self.radio_btn_change(name))) frame_with_radio_btns = Frame(parent) first_option = Radiobutton(frame_with_radio_btns, text=text[0], variable=v, value=1) first_option.grid(row=0, column=0, sticky=W+N, padx=2) v.set(1) second_option = Radiobutton(frame_with_radio_btns, text=text[1], variable=v, value=2) second_option.grid(row=1, column=0, sticky=W+N, padx=2) if add_both: both = Radiobutton(frame_with_radio_btns, text='Both', variable=v, value=3) both.grid(row=3, column=0, sticky=W+N, padx=2) frame_with_radio_btns.grid(row=row_index, column=column_index, padx=1, pady=5, sticky=W+N) def radio_btn_change(self, name, *args): ''' Actions that happen when user clicks on a Radiobutton. Changes the corresponding parameter values and options. Args: name (str): name of the parameter that is a key in options dictionary. *args: are provided by IntVar trace method and are ignored in this method. ''' count = self.options[name].get() self.params.update_parameter(name, COUNT_TO_NAME_RADIO_BTN[name, count]) dea_form = COUNT_TO_NAME_RADIO_BTN[name, count] if self.max_slack_box: # on creation it is None if dea_form == 'multi': # disable max slacks self.max_slack_box.config(state=DISABLED) self.params.update_parameter('MAXIMIZE_SLACKS', '') elif dea_form == 'env': self.max_slack_box.config(state=NORMAL) if self.options['MAXIMIZE_SLACKS'].get() == 1: self.params.update_parameter('MAXIMIZE_SLACKS', 'yes') def change_categorical_box(self): ''' Updates categories that can be chosen as categorical category when the user clicks on the Combobox. ''' values = [category for category in self.current_categories if category and category not in self.input_categories_frame.category_objects.keys() and category not in self.output_categories_frame.category_objects.keys()] values.append('') self.categorical_box.config(values=values) def on_categorical_box_change(self, *args): ''' Updates value of the CATEGORICAL_CATEGORY in parameters. This method is called when the user clicks on the Combobox and chooses one item from the drop-down list. Args: *args: are provided by the StringVar trace method and are ignored in this method. ''' categorical_var = self.combobox_text_var.get() self.params.update_parameter('CATEGORICAL_CATEGORY', categorical_var) def set_params_values(self): ''' Reads all parameter values from the parameter object (params) and sets all widgets and options to these read values. Might display warnings if invalid values are stored in parameter object. ''' self.set_radio_btns() self.set_check_btns() self.change_categorical_box() self.set_categorical_box(self.params.get_parameter_value( 'CATEGORICAL_CATEGORY')) self.set_multi_tol() def set_radio_btns(self): ''' Goes through all Radiobuttons and changes their values according to the values stored in parameter object. Might display warnings. ''' self.set_one_radio_btn('RETURN_TO_SCALE', ['VRS', 'CRS', 'both']) self.set_one_radio_btn('ORIENTATION', ['input', 'output', 'both']) self.set_one_radio_btn('DEA_FORM', ['env', 'multi']) def set_one_radio_btn(self, param_name, valid_values): ''' Sets value of a given set of Radiobuttons according to its value stored in parameter object if this value is valid. Might display warnings. Args: param_name (str): name of parameter whose value must be changed. valid_values (list of str): list of valid values that this parameter might take. ''' param_value = self.params.get_parameter_value(param_name) for count, value in enumerate(valid_values): if param_value == value: self.options[param_name].set(count + 1) return self._show_warning(param_name) self.options[param_name].set(1) def _show_warning(self, param_name): ''' Displays a warning saying that a value of a given parameter is not valid. Args: param_name (str): name of the parameter. ''' showwarning('Warning', 'Parameter <{0}> does not have valid values.' ' It will be set to default'. format(param_name)) def set_check_btns(self): ''' Goes through all Checkbuttons and changes their values according to the values stored in parameter object. Might display warnings. ''' self.set_one_check_btn('MAXIMIZE_SLACKS') self.set_one_check_btn('PEEL_THE_ONION') self.set_one_check_btn('USE_SUPER_EFFICIENCY') def set_one_check_btn(self, param_name): ''' Sets value of a given set of Checkbutton according to its value stored in parameter object if this value is valid. Might display warnings. Args: param_name (str): name of parameter whose value must be changed. ''' param_value = self.params.get_parameter_value(param_name) if param_value: self.options[param_name].set(1) def set_categorical_box(self, categorical_param): ''' Sets the value of Combobox with categorical category according to a given value if this value is in the list of values of this Combobox. If the given value is not in the list of values, a warning is displayed. Args: categorical_param (str): value of the categorical category. ''' if categorical_param in self.categorical_box.cget('values'): self.combobox_text_var.set(categorical_param) else: self._show_warning_combobox(categorical_param) def _show_warning_combobox(self, categorical_param): ''' Displays a warning saying that a value of a given parameter is not a valid categorical category. Args: categorical_param (str): name of the categorical category. ''' showwarning('Warning', 'Category: <{0}> cannot be chosen as a ' 'categorical variable'. format(categorical_param)) def set_multi_tol(self): ''' Sets the value of Entry with multiplier model tolerance according to a given value if this value is valid (non-negative float). If the given value is invalid, a warning is displayed. ''' tol_str = self.params.get_parameter_value('MULTIPLIER_MODEL_TOLERANCE') try: tol = float(tol_str) if (tol < 0): self._show_multi_tol_warning(tol_str) self.multi_tol_strvar.set('0') else: self.multi_tol_strvar.set(tol_str) except ValueError: self._show_multi_tol_warning(tol_str) self.multi_tol_strvar.set('0') def _show_multi_tol_warning(self, tol_str): ''' Displays a warning saying that a value of a multiplier model tolerance is invalid. Args: tol_str (str): value of the multiplier model tolerance. ''' showwarning('Warning', 'Value: <{0}> is not valid as a multiplier' ' model tolerance'. format(tol_str)) def on_multi_tol_change(self, *args): ''' Updates parameter MULTIPLIER_MODEL_TOLERANCE in the parameter object when the user modifies the content of the Entry widget that stores multiplier model tolerance. Args: *args: are provided by the StringVar trace method and are ignored in this method. ''' # this parameter will be validated before run tol_str = self.multi_tol_strvar.get() self.params.update_parameter('MULTIPLIER_MODEL_TOLERANCE', tol_str) def on_check_box_click(self, var, name): ''' Updates parameter specified by the Checkbutton in the parameter object when the user clicks on the Checkbutton. Args: var (IntVar): IntVar of the Checkbutton. name (str): name of the parameter that is the key in options dictionary. ''' if var.get() == 1: self.params.update_parameter(name, 'yes') else: self.params.update_parameter(name, '')
def student_new_record(): global screen4 semester = StringVar() entryField = list() screen4 = Toplevel(screen) screen4.title("New Record") adjustWindow(screen4) # configuring the window Label(screen4, text="Enter New Record", width='40', height="2", font=("Calibri", 22, 'bold'), fg='white', bg='#d9660a').grid(row=0, sticky='w', columnspan=4) #Label(screen4, text="", bg='#174873', width='60', height='18').place(x=0, y=127) #Label(screen4, text="", bg='white',width='100', height='1').place(x=0,y=80) Label(screen4, text="", bg='white', width='86', height='1').grid(row=1, columnspan=4) Label(screen4, text="Subject Name", font=("Open Sans", 12, 'bold'), fg='white', bg='#174873').grid(row=2, column=0, pady=(5, 10)) Label(screen4, text="Your Marks", font=("Open Sans", 12, 'bold'), fg='white', bg='#174873').grid(row=2, column=1, pady=(5, 10)) Label(screen4, text="Out of", font=("Open Sans", 12, 'bold'), fg='white', bg='#174873').grid(row=2, column=2, pady=(5, 10)) Label(screen4, text="Credits Points", font=("Open Sans", 12, 'bold'), fg='white', bg='#174873').grid(row=2, column=3, pady=(5, 10)) rowNo = 3 for i in range( 6 ): # this loop will generate all input field for taking input from the user temp = list() for j in range(4): e = Entry(screen4, width=14) e.grid(row=rowNo, column=j, padx=(3, 0), pady=(0, 25)) temp.append(e) entryField.append(temp) rowNo += 2 Label(screen4, text="Select Sem:", font=("Open Sans", 12, 'bold'), fg='white', bg='#174873').grid(row=rowNo, column=0, pady=(15, 0)) list1 = ['1', '2', '3', '4', '5', '6', '7', '8'] droplist = OptionMenu(screen4, semester, *list1) semester.set('--0--') droplist.config(width=5) droplist.grid(row=rowNo, column=1, pady=(15, 0)) Button(screen4, text='Submit', width=20, font=("Open Sans", 13, 'bold'), bg='brown', fg='white', command=lambda: enter_new_record(entryField, semester)).grid( row=rowNo, columnspan=2, column=2, pady=(15, 0))
class CollocationsView: _BACKGROUND_COLOUR='#FFF' #white def __init__(self): self.queue = q.Queue() self.model = CollocationsModel(self.queue) self.top = Tk() self._init_top(self.top) self._init_menubar() self._init_widgets(self.top) self.load_corpus(self.model.DEFAULT_CORPUS) self.after = self.top.after(POLL_INTERVAL, self._poll) def _init_top(self, top): top.geometry('550x650+50+50') top.title('NLTK Collocations List') top.bind('<Control-q>', self.destroy) top.protocol('WM_DELETE_WINDOW', self.destroy) top.minsize(550,650) def _init_widgets(self, parent): self.main_frame = Frame(parent, dict(background=self._BACKGROUND_COLOUR, padx=1, pady=1, border=1)) self._init_corpus_select(self.main_frame) self._init_results_box(self.main_frame) self._init_paging(self.main_frame) self._init_status(self.main_frame) self.main_frame.pack(fill='both', expand=True) def _init_corpus_select(self, parent): innerframe = Frame(parent, background=self._BACKGROUND_COLOUR) self.var = StringVar(innerframe) self.var.set(self.model.DEFAULT_CORPUS) Label(innerframe, justify=LEFT, text=' Corpus: ', background=self._BACKGROUND_COLOUR, padx = 2, pady = 1, border = 0).pack(side='left') other_corpora = list(self.model.CORPORA.keys()).remove(self.model.DEFAULT_CORPUS) om = OptionMenu(innerframe, self.var, self.model.DEFAULT_CORPUS, command=self.corpus_selected, *self.model.non_default_corpora()) om['borderwidth'] = 0 om['highlightthickness'] = 1 om.pack(side='left') innerframe.pack(side='top', fill='x', anchor='n') def _init_status(self, parent): self.status = Label(parent, justify=LEFT, relief=SUNKEN, background=self._BACKGROUND_COLOUR, border=0, padx = 1, pady = 0) self.status.pack(side='top', anchor='sw') def _init_menubar(self): self._result_size = IntVar(self.top) menubar = Menu(self.top) filemenu = Menu(menubar, tearoff=0, borderwidth=0) filemenu.add_command(label='Exit', underline=1, command=self.destroy, accelerator='Ctrl-q') menubar.add_cascade(label='File', underline=0, menu=filemenu) editmenu = Menu(menubar, tearoff=0) rescntmenu = Menu(editmenu, tearoff=0) rescntmenu.add_radiobutton(label='20', variable=self._result_size, underline=0, value=20, command=self.set_result_size) rescntmenu.add_radiobutton(label='50', variable=self._result_size, underline=0, value=50, command=self.set_result_size) rescntmenu.add_radiobutton(label='100', variable=self._result_size, underline=0, value=100, command=self.set_result_size) rescntmenu.invoke(1) editmenu.add_cascade(label='Result Count', underline=0, menu=rescntmenu) menubar.add_cascade(label='Edit', underline=0, menu=editmenu) self.top.config(menu=menubar) def set_result_size(self, **kwargs): self.model.result_count = self._result_size.get() def _init_results_box(self, parent): innerframe = Frame(parent) i1 = Frame(innerframe) i2 = Frame(innerframe) vscrollbar = Scrollbar(i1, borderwidth=1) hscrollbar = Scrollbar(i2, borderwidth=1, orient='horiz') self.results_box = Text(i1, font=tkinter.font.Font(family='courier', size='16'), state='disabled', borderwidth=1, yscrollcommand=vscrollbar.set, xscrollcommand=hscrollbar.set, wrap='none', width='40', height = '20', exportselection=1) self.results_box.pack(side='left', fill='both', expand=True) vscrollbar.pack(side='left', fill='y', anchor='e') vscrollbar.config(command=self.results_box.yview) hscrollbar.pack(side='left', fill='x', expand=True, anchor='w') hscrollbar.config(command=self.results_box.xview) #there is no other way of avoiding the overlap of scrollbars while using pack layout manager!!! Label(i2, text=' ', background=self._BACKGROUND_COLOUR).pack(side='left', anchor='e') i1.pack(side='top', fill='both', expand=True, anchor='n') i2.pack(side='bottom', fill='x', anchor='s') innerframe.pack(side='top', fill='both', expand=True) def _init_paging(self, parent): innerframe = Frame(parent, background=self._BACKGROUND_COLOUR) self.prev = prev = Button(innerframe, text='Previous', command=self.previous, width='10', borderwidth=1, highlightthickness=1, state='disabled') prev.pack(side='left', anchor='center') self.next = next = Button(innerframe, text='Next', command=self.__next__, width='10', borderwidth=1, highlightthickness=1, state='disabled') next.pack(side='right', anchor='center') innerframe.pack(side='top', fill='y') self.reset_current_page() def reset_current_page(self): self.current_page = -1 def _poll(self): try: event = self.queue.get(block=False) except q.Empty: pass else: if event == CORPUS_LOADED_EVENT: self.handle_corpus_loaded(event) elif event == ERROR_LOADING_CORPUS_EVENT: self.handle_error_loading_corpus(event) self.after = self.top.after(POLL_INTERVAL, self._poll) def handle_error_loading_corpus(self, event): self.status['text'] = 'Error in loading ' + self.var.get() self.unfreeze_editable() self.clear_results_box() self.freeze_editable() self.reset_current_page() def handle_corpus_loaded(self, event): self.status['text'] = self.var.get() + ' is loaded' self.unfreeze_editable() self.clear_results_box() self.reset_current_page() #self.next() collocations = self.model.next(self.current_page + 1) self.write_results(collocations) self.current_page += 1 def corpus_selected(self, *args): new_selection = self.var.get() self.load_corpus(new_selection) def previous(self): self.freeze_editable() collocations = self.model.prev(self.current_page - 1) self.current_page= self.current_page - 1 self.clear_results_box() self.write_results(collocations) self.unfreeze_editable() def __next__(self): self.freeze_editable() collocations = self.model.next(self.current_page + 1) self.clear_results_box() self.write_results(collocations) self.current_page += 1 self.unfreeze_editable() def load_corpus(self, selection): if self.model.selected_corpus != selection: self.status['text'] = 'Loading ' + selection + '...' self.freeze_editable() self.model.load_corpus(selection) def freeze_editable(self): self.prev['state'] = 'disabled' self.next['state'] = 'disabled' def clear_results_box(self): self.results_box['state'] = 'normal' self.results_box.delete("1.0", END) self.results_box['state'] = 'disabled' def fire_event(self, event): #Firing an event so that rendering of widgets happen in the mainloop thread self.top.event_generate(event, when='tail') def destroy(self, *e): if self.top is None: return self.top.after_cancel(self.after) self.top.destroy() self.top = None def mainloop(self, *args, **kwargs): if in_idle(): return self.top.mainloop(*args, **kwargs) def unfreeze_editable(self): self.set_paging_button_states() def set_paging_button_states(self): if self.current_page == -1 or self.current_page == 0: self.prev['state'] = 'disabled' else: self.prev['state'] = 'normal' if self.model.is_last_page(self.current_page): self.next['state'] = 'disabled' else: self.next['state'] = 'normal' def write_results(self, results): self.results_box['state'] = 'normal' row = 1 for each in results: self.results_box.insert(str(row) + '.0', each[0] + " " + each[1] + "\n") row += 1 self.results_box['state'] = 'disabled'
class GUIRunner(object): ''' classdocs ''' if __name__ == "__main__": from GUIRunner import GUIRunner window = GUIRunner() def __init__(self, sizeRatio=1 / 3, circleSize=500, circleRatio=1 / 2): ''' Creates a GUI with a Window that's sized based on sizeRatio, with a circle on a canvas based on circleSize and circleRatio. Works fine if called without any parameters. ''' self.top = tk.Tk() ratio = sizeRatio moddedWidth = int(1920 * ratio) moddedHeight = int(1080 * ratio) self.top.title("Pi-based Data Encoder/Decoder") #generates a frame to show the data in the encoder self.dataFrame = tk.LabelFrame( self.top, text="Data: Type Here! or Load a File (This can scroll)" ) # height=moddedHeight, width=moddedWidth self.dataScroll = tk.Scrollbar(self.dataFrame) self.dataScroll.pack(side=tk.RIGHT, fill=tk.Y) self.dataFrameTArea = tk.Text(self.dataFrame, relief=tk.RAISED, width=70, yscrollcommand=self.dataScroll.set) self.dataToInsert = "" self.dataFrameTArea.pack(fill=tk.BOTH) self.dataScroll.config(command=self.dataFrameTArea.yview) self.errorLabelVar = StringVar(value="Errors will appear here") self.errorLabel = tk.Label(self.dataFrame, textvariable=self.errorLabelVar) self.errorLabel.pack() self.dataFrame.pack(side=tk.RIGHT) #supposed to center the window winWidth = self.top.winfo_reqwidth() winHeight = self.top.winfo_reqheight() xPos = int((self.top.winfo_screenwidth() - winWidth) / 4) yPos = int((self.top.winfo_screenheight() - winHeight) / 4) #generates a frame to hold the canvas (for the pi chart) self.piFrame = tk.LabelFrame(self.top, text="Pi Display") self.piFrame.pack(side=tk.TOP) #finds the bounding box for the Circles on the canvas, then draws the base circle and generates the ID for the arcs self.piDisplay = tk.Canvas(self.piFrame, bg="gray", height=moddedHeight, width=moddedWidth) circleSize = circleSize circleRatio = circleRatio moddedCircle = int(circleSize * circleRatio) canvWidth = self.piDisplay.winfo_reqwidth() canvHeight = self.piDisplay.winfo_reqheight() self.piBoundingBox = (canvWidth - moddedCircle) / 2, ( canvHeight - moddedCircle) / 2, (canvWidth + moddedCircle) / 2, ( canvHeight + moddedCircle) / 2 self.piDisplay.create_oval(self.piBoundingBox, fill="black") self.startValue = 0 self.endValue = 10000 self.startDegree = 0 self.endDegree = 0 self.arcID = self.piDisplay.create_arc(self.piBoundingBox, start=self.startDegree, extent=self.endDegree, fill="red") self.piDisplay.pack() #generates a frame to hold UI widgets. self.UIFrame = tk.LabelFrame(self.top, bg="white", text="Play with me!") self.UIFrame.pack() #generates an info frame to go below the canvas, for labels and text entries self.infoFrame = tk.Frame(self.UIFrame) self.piStringLengthVar = StringVar() self.piStringLengthVar.set("Pi String Size Goes Here") self.piStringLabel = tk.Label(self.infoFrame, textvariable=self.piStringLengthVar) self.piStringLabel.pack() self.startValueLabel = tk.Label(self.infoFrame, text="Pi String Lower Bound:") self.startValueLabel.pack() self.startValueVar = StringVar() self.startValueTArea = tk.Entry(self.infoFrame, textvariable=self.startValueVar, exportselection=0) self.startValueTArea.pack() self.endValueLabel = tk.Label(self.infoFrame, text="Pi String Upper Bound:") self.endValueLabel.pack() self.endValueVar = StringVar() self.endValueTArea = tk.Entry(self.infoFrame, textvariable=self.endValueVar, exportselection=0) self.endValueTArea.pack() self.infoFrame.pack() #generates another frame to go below the canvas, this one holds buttons self.buttonFrame = tk.Frame(self.UIFrame) self.updateArcButton = tk.Button(self.buttonFrame, text="Update Arc", fg="black", command=partial(self.updateArc)) self.resetArcButton = tk.Button(self.buttonFrame, text="Reset Arc", fg="black", command=partial(self.resetArc)) self.loadFileButton = tk.Button(self.buttonFrame, text="Load a File", fg="black", command=partial(self.loadFromFile)) self.saveFileButton = tk.Button(self.buttonFrame, text="Save to File", fg="black", command=partial(self.saveToFile)) #self.button5 = tk.Button(self.buttonFrame, text="Update Data", fg="black",command=partial(self.updateDataFrame)) #kind of useless ngl self.clearDataButton = tk.Button(self.buttonFrame, text="Clear Data", fg="black", command=partial(self.clearDataFrame)) self.encodeButton = tk.Button(self.buttonFrame, text="Encode Data", fg="black", command=partial(self.encode)) self.decodeButton = tk.Button(self.buttonFrame, text="Decode Data", fg="black", command=partial(self.decode)) self.updateArcButton.pack(side=tk.LEFT) self.resetArcButton.pack(side=tk.LEFT) #self.button5.pack(side=tk.LEFT) self.loadFileButton.pack(side=tk.RIGHT) self.saveFileButton.pack(side=tk.RIGHT) self.clearDataButton.pack(side=tk.LEFT) self.encodeButton.pack(side=tk.LEFT) self.decodeButton.pack(side=tk.LEFT) self.buttonFrame.pack() #spawns window, sets some variables to default values self.top.geometry("+{0}+{1}".format(xPos, yPos)) self.resetArc() self.startValueVar.set("0") self.endValueVar.set("10000") self.dataToInsert = "How To Use This:\nClick Encode Data to turn any text/numbers written here into a string of numbers.\nThis string is based on the numbers you enter for the Pi String bounds. You can also just use the default values.\nOnce you have that encoded string, click Decode Data to return it to readable text. This is also based on the Pi String bound values, so make sure to encode and decode data using the same bounds both times.\n Otherwise you can enter whatever values for pi you want, and if the program has a problem with it (see below for the error bar), it will let you know.\nIf it doesn't work, try increasing the distance between the two bounds. Also, you can try encoding something multiple times (like 3 times), then decoding it that many times to return to the original input. But remember, the bounds have to be the same when you're encoding and decoding the same data. \nUse Update Arc to update the circle display (which represents a slice of pi that you've selected) without Encoding/Decoding anything. Use Reset Arc to reset the bounds and the pi display. I don't really know a reason for it, because you can just change both bounds and click Update, but you can do it.\nLoad a File reads data from a text file and loads it in the Data frame. Save to File takes the data in the frame and saves it to a text file. This is so you can save long encoded strings or something.\nThanks for looking at this!\n-Samihan" self.updateDataFrame() self.top.mainloop() #GUI functions def resetArc(self): ''' Resets arc drawing. ''' self.piDisplay.delete(self.arcID) self.startValueVar.set("") self.endValueVar.set("") def redrawPiSlice(self): ''' Redraws an arc on top of the main circle on the canvas. Uses the class variables startDegree and endDegree. Deletes the old arc based on the arcID parameter. Sets the paramater arcID to the arc that gets drawn. ''' self.piDisplay.delete( self.arcID ) #put this in a try if it throws an error if theres nothing to delete, so far it looks fine arc = self.piDisplay.create_arc(self.piBoundingBox, start=self.startDegree, extent=self.endDegree - self.startDegree, fill="red") self.arcID = arc def updateArc(self): ''' Calls updateDegrees and redrawPiSlice. ''' validDegrees = self.updateDegrees() if (validDegrees): self.redrawPiSlice() def updateDegrees(self): ''' Calls both readStartValue and readEndValue. Sets the piStringLength to the endValue rounded up to the nearest 10000. Determines the degree to pi character ratio, then calculates the startDegree and endDegree values based on that. Returns true if no errors occur. ''' success = False self.updateErrorLabel("") #clearing the error frame validStart = self.readStartValue() validEnd = self.readEndValue() if (validStart and validEnd): self.piStringLength = self.endValue + (10000 - self.endValue % 10000) self.piStringLengthVar.set("Max Pi Length: " + str(self.piStringLength)) self.degreeToCharRatio = self.piStringLength / 360 self.startDegree = self.startValue / self.degreeToCharRatio self.endDegree = self.endValue / self.degreeToCharRatio success = True return success def readStartValue(self): ''' Reads the value in the startValueTArea If there's nothing to read, show the error in the error label. Returns true if no error occurs. ''' success = False try: rawValue = int(self.startValueVar.get()) self.startValue = rawValue success = True except: self.updateErrorLabel("Pi String Bound Error") return success def readEndValue(self): ''' Reads the value in the endValueTArea If there's nothing to read, show the error in the error label. Returns true if no error occurs. ''' success = False try: rawValue = int(self.endValueVar.get()) self.endValue = rawValue success = True except: self.updateErrorLabel("Pi String Bound Error") return success def loadFromFile(self): ''' Opens a browse for file window, then reads it for data. Stores to dataToInsert, then calls updateDataFrame If the file type isn't readable, show the error in the error label. Returns true if no error occurs. ''' success = False file = tk.filedialog.askopenfile(initialdir="/", mode="r", filetypes=(("Text File", "*.txt"), ("All Files", "*.*"))) if file is None: #exit if dialog is cancelled return success fileData = "" try: for line in file: fileData += str(line) self.dataToInsert = fileData self.updateDataFrame() success = True except: self.updateErrorLabel("The selected file wasn't readable") return success def saveToFile(self): ''' Opens a save as window, then saves the data currently in the dataFrameTArea. Returns true if no error occurs. ''' success = False file = tk.filedialog.asksaveasfile(initialdir="/", defaultextension=".txt", filetypes=(("Text File", "*.txt"), ("All Files", "*.*"))) if file == "" or file is None: #exit if dialog is cancelled return success file.write(self.dataFrameTArea.get(1.0, tk.END)) success = True return success def clearDataFrame(self): ''' Clears the text in the data frame. ''' self.dataFrameTArea.delete(1.0, tk.END) def insertIntoDataFrame(self): ''' Inserts the string in dataToInsert into the data frame. ''' self.dataFrameTArea.insert(1.0, self.dataToInsert) def updateDataFrame(self): ''' Calls clearDataFrame then insertIntoDataFrame ''' self.clearDataFrame() self.insertIntoDataFrame() def updateErrorLabel(self, errorString=""): ''' Replaces the errorLabel with what's in errorLabel Value. ''' self.errorLabelVar.set(errorString) def encode(self): ''' Refreshes the entered degree values and the arc. Then generates a length of pi based on the entered pi limits. It tries to encode the entered data. If it fails, it cancels the whole thing and prints an error message to the error label. Otherwise it prints the encoded data in the data frame. ''' validDegrees = self.updateDegrees() self.updateArc() if (validDegrees): heldData = self.dataFrameTArea.get(1.0, tk.END) heldData = heldData[: -1] #removing the newline character at the end of the dataframe try: sliceBounds = [self.startValue, self.endValue] encodedData = self.encodeByBounds(heldData, sliceBounds) encodedDataString = "" for index in encodedData: if ( index == -1 ): #this triggers if any codon is not found in the pi string. it terminates the encode process. raise encodedDataString += str(index) encodedDataString += "." encodedDataString = encodedDataString[:-1] self.dataToInsert = encodedDataString self.updateDataFrame() except: self.updateErrorLabel( "ENCODE FAILED - Increase the bounds or load different data." ) def decode(self): ''' Refreshes the entered degree values and the arc. Then generates a length of pi based on the entered pi limits. It tries to decode the entered data. If it fails, it cancels the whole thing and prints an error message to the error label. Otherwise it prints the decoded data in the data frame. ''' validDegrees = self.updateDegrees() self.updateArc() if (validDegrees): heldData = self.dataFrameTArea.get(1.0, tk.END) heldData = heldData[: -1] #removing the newline character at the end of the dataframe heldData = str(heldData) indexList = heldData.split('.') try: sliceBounds = [self.startValue, self.endValue] decodedData = self.decodeByBounds(indexList, sliceBounds) self.dataToInsert = decodedData self.updateDataFrame() except: self.updateErrorLabel( "DECODE FAILED - Increase the bounds or load different data" ) #basic runner/encoder functions def pi_chudnovsky_bs(self, digits): """ Compute int(pi * 10**digits) This is done using Chudnovsky's series with binary splitting taken from https://www.craig-wood.com/nick/pub/pymath/pi_chudnovsky_bs_gmpy.py requires installation of https://pypi.python.org/pypi/gmpy2 """ C = 640320 C3_OVER_24 = C**3 // 24 def bs(a, b): """ Computes the terms for binary splitting the Chudnovsky infinite series a(a) = +/- (13591409 + 545140134*a) p(a) = (6*a-5)*(2*a-1)*(6*a-1) b(a) = 1 q(a) = a*a*a*C3_OVER_24 returns P(a,b), Q(a,b) and T(a,b) """ if b - a == 1: # Directly compute P(a,a+1), Q(a,a+1) and T(a,a+1) if a == 0: Pab = Qab = mpz(1) else: Pab = mpz((6 * a - 5) * (2 * a - 1) * (6 * a - 1)) Qab = mpz(a * a * a * C3_OVER_24) Tab = Pab * (13591409 + 545140134 * a) # a(a) * p(a) if a & 1: Tab = -Tab else: # Recursively compute P(a,b), Q(a,b) and T(a,b) # m is the midpoint of a and b m = (a + b) // 2 # Recursively calculate P(a,m), Q(a,m) and T(a,m) Pam, Qam, Tam = bs(a, m) # Recursively calculate P(m,b), Q(m,b) and T(m,b) Pmb, Qmb, Tmb = bs(m, b) # Now combine Pab = Pam * Pmb Qab = Qam * Qmb Tab = Qmb * Tam + Pam * Tmb return Pab, Qab, Tab # how many terms to compute DIGITS_PER_TERM = math.log10(C3_OVER_24 / 6 / 2 / 6) N = int(digits / DIGITS_PER_TERM + 1) # Calclate P(0,N) and Q(0,N) P, Q, T = bs(0, N) one_squared = mpz(10)**(2 * digits) sqrtC = gmpy2.isqrt((10005 * one_squared)) return (Q * 426880 * sqrtC) // T # The last 5 digits or pi for various numbers of digits check_digits = { 100: 70679, 1000: 1989, 10000: 75678, 100000: 24646, 1000000: 58151, 10000000: 55897, } def getPi(self, length=8555, startLength=0): ''' A way for me to call pi_chudnovsky_bs that allows me to easily call it and request for substrings beyond a certain initial length. Useful for slicing pi based on breakpoints determined by piSlicer. getPi(breakpoint2, breakpoint1) where breakpoint2 > breakpoint 1 and they're both exact values determined from piSlicer Defaults to 8555 because that's the first breakpoint with codon length = 3 with codons going from 0 - 999. Actually returns a length of 2 more than the length parameter. Intentionally. ''' pi = self.pi_chudnovsky_bs( length + 1 ) #this is length+1 because breakpoint 13 fails without it. I have a hypothesis about this where the breakpoint works 99% of the time because of RNG but it's not really supposed to without the +1 piString = str(pi) piString = piString[startLength:] return piString def encodeByBounds(self, inputToEncode, sliceBounds=[0, 3853]): ''' Takes an input (int or string, whatever) and encodes it based on the given sliceBounds. Defaults to the first slice for codons of length 3 ranging from 0 to 128. Assumes the slice contains all codons required to encode the input. Returns an array of codons that represent the indices of pi where the input data is found in the piSlice. ''' piString = self.getPi(sliceBounds[1], sliceBounds[0]) encoder = Encoder() stringToEncode = str(inputToEncode) asciiString = encoder.stringToAscii(stringToEncode) asciiSlices = encoder.numStringSlicer(asciiString) codonSubbedSlices = encoder.codonSubstituter(asciiSlices, piString) return codonSubbedSlices def decodeByBounds(self, inputToDecode, sliceBounds=[0, 3853]): ''' Takes an input (array of codons) and decodes it based on the given sliceBounds. Defaults to the first slice for codons of length 3 ranging from 0 to 128. Assumes the slice contains all codons required to decode the input. Returns a string of concatenated characters based on the ascii code that the codons represented.. ''' piString = self.getPi(sliceBounds[1], sliceBounds[0]) encoder = Encoder() asciiSubbedSlices = encoder.codonTranslator(inputToDecode, piString) reconstitutedString = encoder.asciiToString(asciiSubbedSlices) return reconstitutedString
bon1 = PhotoImage(file="bonhomme1.gif") bon2 = PhotoImage(file="bonhomme2.gif") bon3 = PhotoImage(file="bonhomme3.gif") bon4 = PhotoImage(file="bonhomme4.gif") bon5 = PhotoImage(file="bonhomme5.gif") bon6 = PhotoImage(file="bonhomme6.gif") bon7 = PhotoImage(file="bonhomme7.gif") bon8 = PhotoImage(file="bonhomme8.gif") photoliste = [bon8, bon7, bon6, bon5, bon4, bon3, bon2, bon1] #Initialisation des variables mot = fMots(fFichier()) LE = '' E = IntVar() pT = StringVar() pT.set(fTiret(mot)) #Creation d'un widget frame dans la fenetre principale frame1 = Frame(Mafenetre, relief='groove') frame1.pack(side='left', padx=10, pady=10) #Creation d'un bouton pour quitter BoutonQuitter = Button(Mafenetre, text="Quitter", command=Mafenetre.destroy) BoutonQuitter.pack(padx=5, pady=5) #Creation d'un widget entry champ = Entry(Mafenetre) champ.focus_set() champ.pack(padx=5, pady=5) #Creation d'un widget Label et d'un widget Button dans un widget Frame
class Sensitivity: def __init__(self, root): self.root = root self.root.title("Sensitivity") #Title of the Window. self.root.resizable(0, 0) #The window created cannot change size. #First row Labels self.BoxLabel = tk.Label(root, text="Box:") self.BoxLabel.grid(row=0, column=0) self.OneLabel = tk.Label(root, text="One") self.OneLabel.grid(row=0, column=1) self.TwoLabel = tk.Label(root, text="Two") self.TwoLabel.grid(row=0, column=2) self.ThreeLabel = tk.Label(root, text="Three") self.ThreeLabel.grid(row=0, column=3) self.FourLabel = tk.Label(root, text="Four") self.FourLabel.grid(row=0, column=4) def Save(): #Save entry values global UpperOne, UpperTwo, UpperThree, UpperFour, LowerOne, LowerTwo, LowerThree, LowerFour #Upper limits if CheckFloat.CheckFloat( self.UpperOneEntry.get()) == True: #Check input is float if float(self.UpperOneEntry.get()) >= 0 and float( self.UpperOneEntry.get()) <= 1: #Check between 1 and 0 UpperOne = self.UpperOneEntry.get() else: print("Error") else: print("Error") if CheckFloat.CheckFloat( self.UpperTwoEntry.get()) == True: #Check input is float if float(self.UpperTwoEntry.get()) >= 0 and float( self.UpperTwoEntry.get()) <= 1: #Check between 1 and 0 UpperTwo = self.UpperTwoEntry.get() else: print("Error") else: print("Error") if CheckFloat.CheckFloat( self.UpperThreeEntry.get()) == True: #Check input is float if float(self.UpperThreeEntry.get()) >= 0 and float( self.UpperThreeEntry.get( )) <= 1: #Check between 1 and 0 UpperThree = self.UpperThreeEntry.get() else: print("Error") else: print("Error") if CheckFloat.CheckFloat( self.UpperFourEntry.get()) == True: #Check input is float if float(self.UpperFourEntry.get()) >= 0 and float( self.UpperFourEntry.get( )) <= 1: #Check between 1 and 0 UpperFour = self.UpperFourEntry.get() else: print("Error") else: print("Error") #Lower limits if CheckFloat.CheckFloat( self.LowerOneEntry.get()) == True: #Check input is float if float(self.LowerOneEntry.get()) >= 0 and float( self.LowerOneEntry.get()) <= 1: #Check between 1 and 0 LowerOne = self.LowerOneEntry.get() else: print("Error") else: print("Error") if CheckFloat.CheckFloat( self.LowerTwoEntry.get()) == True: #Check input is float if float(self.LowerTwoEntry.get()) >= 0 and float( self.LowerTwoEntry.get()) <= 1: #Check between 1 and 0 LowerTwo = self.LowerTwoEntry.get() else: print("Error") else: print("Error") if CheckFloat.CheckFloat( self.LowerThreeEntry.get()) == True: #Check input is float if float(self.LowerThreeEntry.get()) >= 0 and float( self.LowerThreeEntry.get( )) <= 1: #Check between 1 and 0 LowerThree = self.LowerThreeEntry.get() else: print("Error") else: print("Error") if CheckFloat.CheckFloat( self.LowerFourEntry.get()) == True: #Check input is float if float(self.LowerFourEntry.get()) >= 0 and float( self.LowerFourEntry.get( )) <= 1: #Check between 1 and 0 LowerFour = self.LowerFourEntry.get() else: print("Error") else: print("Error") #Second row Labels self.DetectionLabel = tk.Label(root, text="Detection Value:") self.DetectionLabel.grid(row=1, column=0) self.DetectionOneLabel = tk.Label(root, text="...", borderwidth=2, relief='ridge') self.DetectionOneLabel.grid(row=1, column=1) self.DetectionTwoLabel = tk.Label(root, text="...", borderwidth=2, relief='ridge') self.DetectionTwoLabel.grid(row=1, column=2) self.DetectionThreeLabel = tk.Label(root, text="...", borderwidth=2, relief='ridge') self.DetectionThreeLabel.grid(row=1, column=3) self.DetectionFourLabel = tk.Label(root, text="...", borderwidth=2, relief='ridge') self.DetectionFourLabel.grid(row=1, column=4) #Third row Labels and Entry widgets self.UpperLimitLabel = tk.Label(root, text="Upper Limit:") self.UpperLimitLabel.grid(row=2, column=0) self.UpperOneEntryText = StringVar() self.UpperOneEntry = tk.Entry(root, textvariable=self.UpperOneEntryText) self.UpperOneEntryText.set(UpperOne) self.UpperOneEntry.grid(row=2, column=1) self.UpperTwoEntryText = StringVar() self.UpperTwoEntry = tk.Entry(root, textvariable=self.UpperTwoEntryText) self.UpperTwoEntryText.set(UpperTwo) self.UpperTwoEntry.grid(row=2, column=2) self.UpperThreeEntryText = StringVar() self.UpperThreeEntry = tk.Entry(root, textvariable=self.UpperThreeEntryText) self.UpperThreeEntryText.set(UpperThree) self.UpperThreeEntry.grid(row=2, column=3) self.UpperFourEntryText = StringVar() self.UpperFourEntry = tk.Entry(root, textvariable=self.UpperFourEntryText) self.UpperFourEntryText.set(UpperFour) self.UpperFourEntry.grid(row=2, column=4) #Fourth row Labels and Entry widgets self.LowerLimitLabel = tk.Label(root, text="Lower Limit:") self.LowerLimitLabel.grid(row=3, column=0) self.LowerOneEntryText = StringVar() self.LowerOneEntry = tk.Entry(root, textvariable=self.LowerOneEntryText) self.LowerOneEntryText.set(LowerOne) self.LowerOneEntry.grid(row=3, column=1) self.LowerTwoEntryText = StringVar() self.LowerTwoEntry = tk.Entry(root, textvariable=self.LowerTwoEntryText) self.LowerTwoEntryText.set(LowerTwo) self.LowerTwoEntry.grid(row=3, column=2) self.LowerThreeEntryText = StringVar() self.LowerThreeEntry = tk.Entry(root, textvariable=self.LowerThreeEntryText) self.LowerThreeEntryText.set(LowerThree) self.LowerThreeEntry.grid(row=3, column=3) self.LowerFourEntryText = StringVar() self.LowerFourEntry = tk.Entry(root, textvariable=self.LowerFourEntryText) self.LowerFourEntryText.set(LowerFour) self.LowerFourEntry.grid(row=3, column=4) self.SaveButton = tk.Button(root, text="Save", width=5, command=Save) self.SaveButton.grid(row=4, column=3, sticky=tk.W + tk.E + tk.N + tk.S) self.root.mainloop()
import tkinter as tk from tkinter import StringVar def change(): v.set("goodbye") #label.pack() window = tk.Tk() # Set the title for your window window.title('Auto Shop') # Set size of window window.geometry("600x600") # Adding a label v = StringVar() title = tk.Label(textvariable=v) v.set('hello') # grid() tells you where you want the label, (0,0) is default title.pack() click = tk.Button(text="Change", bg="blue", command=change) click.pack() window.mainloop()
class NanoporeProspectorMasterFrame(Frame): def __init__(self, root): Frame.__init__(self, root) root.title("Nanopore Prospector") self.parent = root self.initialize() # Initialize GUI elements def initialize(self): # Load the configuration file. loadConfigurationFile() # This is the directory the python executable is running from. FileAndPath = abspath(__file__) self.idir, self.ifile = split(FileAndPath) # GUI options #self.label_opt = {'fill': Tkconstants.BOTH, 'padx': 10, 'pady': 10} self.button_opt = {'fill': BOTH, 'padx': 50, 'pady': 15} self.dir_opt = {'initialdir': self.idir, 'mustexist': True, 'parent': self, 'title': 'Choose a directory'} # A frame for choosing the instructions self.instructionsFrame = self.makeDemultiplexInstructionsFrame() self.instructionsFrame.pack() # Frame forinput/output directories self.chooseDirectoryFrame = self.makeChooseIODirectoriesFrame() self.chooseDirectoryFrame.pack() # Frame for Analysis Options self.analysisButtonsFrame = self.makeAnalysisButtonsFrame() self.analysisButtonsFrame.pack() # Frame for Analysis Log self.logFrame = self.makeAnalysisLogFrame() self.logFrame.pack() # Frame for the More Information Panel self.moreInfoFrame = self.makeMoreInfoFrame() self.moreInfoFrame.pack() # Assemble all the frames and get ready. self.pack() def recordAnalysisStep(self, currentMessage): # The log keeps track of step-by-step things performed by Nanopore Prospector. fullLogMessage = str(datetime.now()) + ' : ' + currentMessage + '\n' # Append the GUI with the Log Entry # TODO: Move to the bottom of the log. The GUI is not updating in real time. # Alternatively, reverse the log and put new stuff on top self.submOutputGuiObject.insert(END, fullLogMessage) logMessageToFile(currentMessage) # This repaints the window, we can see what's going on. self.update() def reportResults(self, currentMessage): # This Report is intended to Summarize the prospector / allele calling results. fullReportMessage = currentMessage + '\n' if (getConfigurationValue('report_file_location') is None): print ('The report file name does not exist yet.\nTrying to report this message:\n' + currentMessage) else: #print ('Logging message: ' + currentMessage) # Append the log with the log entry resultsOutput = open(getConfigurationValue('report_file_location'), 'a') resultsOutput.write(fullReportMessage) resultsOutput.close() def makeDemultiplexInstructionsFrame(self): instructionsFrame = Frame(self) self.instructionText = StringVar() self.instructionText.set('Use this interface to look at a group of \nMinION Reads containing HLA amplicon sequences:') Label(instructionsFrame, width=80, height=5, textvariable=self.instructionText).pack() return instructionsFrame def makeChooseIODirectoriesFrame(self): chooseDirectoryFrame = Frame(self) self.chooseInputButton = Button(chooseDirectoryFrame, text='Choose Input Directory ', command=self.chooseReadInputDirectory) self.chooseInputButton.grid(row=0, column=0, sticky=W) self.chooseOutputButton = Button(chooseDirectoryFrame, text='Choose Output Directory', command=self.chooseReadOutputDirectory) self.chooseOutputButton.grid(row=1, column=0, sticky=W) self.inputDirectoryText = StringVar() self.inputDirectoryText.set('Where is your MinION Read Directory?') Entry(chooseDirectoryFrame, width=60, textvariable=self.inputDirectoryText).grid(row=0, column=1) self.outputDirectoryText = StringVar() self.outputDirectoryText.set('Output Directory') Entry(chooseDirectoryFrame, width=60, textvariable=self.outputDirectoryText).grid(row=1, column=1) return chooseDirectoryFrame def makeAnalysisButtonsFrame(self): analysisButtonsFrame = Frame(self) self.analysisOptionsButton = Button(analysisButtonsFrame, text='Analysis Options', command=self.specifyReadStatOptions) self.analysisOptionsButton.grid(row=0, column=0) self.prepareReadsButton = Button(analysisButtonsFrame, text='Demultiplex + Prepare Reads', command=self.constructInitialReadStats) self.prepareReadsButton.grid(row=1, column=0) self.runAnalysisButton = Button(analysisButtonsFrame, text='Run Full Analysis', command=self.runFullAnalysis) self.runAnalysisButton.grid(row=2, column=0) return analysisButtonsFrame def makeAnalysisLogFrame(self): logFrame = Frame(self) # TODO: Did i set this log label up correctly? self.logLocationText = StringVar() self.logLocationText.set('Choose a read directory to start logging...') Label(logFrame, width=80, height=5, textvariable=self.logLocationText).pack() self.submOutputXScrollbar = Scrollbar(logFrame, orient=HORIZONTAL) self.submOutputXScrollbar.pack(side=BOTTOM, fill=X) self.submOutputYScrollbar = Scrollbar(logFrame) self.submOutputYScrollbar.pack(side=RIGHT, fill=Y) self.submOutputGuiObject = Text( logFrame, width=100, height=10, wrap=NONE , xscrollcommand=self.submOutputXScrollbar.set , yscrollcommand=self.submOutputYScrollbar.set ) self.submOutputXScrollbar.config(command=self.submOutputGuiObject.xview) self.submOutputYScrollbar.config(command=self.submOutputGuiObject.yview) self.submOutputGuiObject.pack() return logFrame def makeMoreInfoFrame(self): moreInfoFrame = Frame(self) self.howToUseButton = Button(moreInfoFrame, text='How to use this tool', command=self.howToUse) self.howToUseButton.grid(row=0, column=0) self.citationButton = Button(moreInfoFrame, text='Contacting or Citing MUMC', command=self.contactInformation) self.citationButton.grid(row=0, column=1) self.saddlebagsButton = Button(moreInfoFrame, text='SaddleBags - A (Novel) Allele Submission Tool', command=self.launchSaddleBags) self.saddlebagsButton.grid(row=0, column=2) return moreInfoFrame def launchSaddleBags(self): #messagebox.showinfo('Need to open allelesub tool','Popup a window containing the allele submission tool please.') # TODO: This works but the interface is messed up. # I think saddlebags is using "self" to assign variables when it shouldnt. They should assign to the frame instead? # Problem is, i should be making a toplevel object. I can fix this. # See how i did it in specifyReadStatOptions # TODO This actually doesn't work at all, I renamed the saddlebags classes. # This should be a toplevel object, not a Tk object. I think. #saddleBagsRoot = Tk() #AlleleGui(saddleBagsRoot).pack() #saddleBagsRoot.mainloop() raise Exception('Implement Saddlebags Interface, this code does not work right now.') def howToUse(self): # TODO: This howToUse method is pretty weak. messagebox.showinfo('Select a directory containing reads.\n' + 'Do some analysis on the reads.' + 'Ben:Fill in better how-to-use instructions.' ) def contactInformation(self): # This method should list contact information for MUMC, and a link to the github page. messagebox.showinfo('Contact Information', 'This software was created at\n' + 'Maastricht University Medical Center\n' + 'Transplantation Immunology\n' + 'Tissue Typing Laboratory.\n' + 'by Ben Matern:\n' + '[email protected]\n\n' + 'Please send Ben your bioinformatics\n' + 'and data related questions.\n\n' + 'all other inquiries can be directed\n' + 'to Marcel Tilanus:\n' + '[email protected]\n\n' ) def specifyReadStatOptions(self): print('Specifying ReadStat Options.....') self.disableGUI() readStatOptionsRoot = Toplevel() readStatOptionsRoot.bind("<Destroy>", self.enableGUI) AnalysisOptionsInputForm(readStatOptionsRoot, self).pack() # Set the X and the Y Position of the options window, so it is nearby. readStatOptionsRoot.update() windowXpos = str(self.parent.winfo_geometry().split('+')[1]) windowYpos = str(self.parent.winfo_geometry().split('+')[2]) newGeometry = (str(readStatOptionsRoot.winfo_width()) + 'x' + str(readStatOptionsRoot.winfo_height()) + '+' + str(windowXpos) + '+' + str(windowYpos)) readStatOptionsRoot.geometry(newGeometry) readStatOptionsRoot.mainloop() def enableGUI(self, event=None): self.toggleGUI(True) def disableGUI(self): self.toggleGUI(False) def toggleGUI(self, isEnabled): #print ('Toggling GUI Widgets:' + str(isEnabled)) newState = (NORMAL if (isEnabled) else DISABLED) # Choosing the widgets individually, this makes the most sense I think. self.chooseInputButton.config(state=newState) self.chooseOutputButton.config(state=newState) self.prepareReadsButton.config(state=newState) self.analysisOptionsButton.config(state=newState) self.runAnalysisButton.config(state=newState) self.howToUseButton.config(state=newState) self.citationButton.config(state=newState) self.saddlebagsButton.config(state=newState) # This repaints the window, we can see what's going on. self.update() def runFullAnalysis(self): #print('Starting a full analysis.....') self.recordAnalysisStep('Starting a full analysis...') # Set the input and output directories self.assignIODirectories() # Start the Analysis report self.reportResults('HLA Analysis') self.reportResults('Start: ' + str(datetime.now())) # 1) Nitpicker to prepare reads self.constructInitialReadStats() # 2) Sort reads by HLA Locus self.sortByLocus() # 3) Assemble each locus file self.assembleSortedReads() # 4) Allele Call results if possible self.alleleCall() # 5) Summarize Results self.summarizeResults() def assignIODirectories(self): assignConfigurationValue('input_directory', self.inputDirectoryText.get()) assignConfigurationValue('output_directory', self.outputDirectoryText.get()) assignConfigurationValue('log_file_location', join(self.outputDirectoryText.get(), 'nanopore-prospector-log.txt')) assignConfigurationValue('report_file_location', join(self.outputDirectoryText.get(), 'AnalysisReport.txt')) #self.consensusSequenceFileName = join(self.outputDirectoryText.get(), 'Consensus.fasta') self.recordAnalysisStep('Initialized Nanopore Prospector Log File') self.recordAnalysisStep('Read Input Directory:' + getConfigurationValue('input_directory')) self.recordAnalysisStep('Analysis Output Directory:' + getConfigurationValue('output_directory')) # TODO Create the results output folder here. def reportReadStats(self, preparedReadResults): self.reportResults('\nRead Statistics:\n') #all_reads, length_rejected, quality_rejected, pass_reads, if ('all_reads' in preparedReadResults.keys()): readLengths = preparedReadResults['all_reads'][0] readQualities = preparedReadResults['all_reads'][1] self.reportResults('All Reads') self.reportResults(str(len(readLengths)) + ' reads analyzed.') self.reportResults('Length (Min/Avg/Max): ' + str(int(amin(readLengths))) + '/' + str(int(mean(readLengths))) + '/' + str(int(amax(readLengths)))) self.reportResults('Q-Score (Min/Avg/Max): ' + str(int(amin(readQualities))) + '/' + str(int(mean(readQualities))) + '/' + str(int(amax(readQualities))) + '\n') if ('pass_reads' in preparedReadResults.keys()): readLengths = preparedReadResults['pass_reads'][0] readQualities = preparedReadResults['pass_reads'][1] self.reportResults('"Pass" Reads') self.reportResults(str(len(readLengths)) + ' reads have the correct length and quality.') self.reportResults('Length (Min/Avg/Max): ' + str(int(amin(readLengths))) + '/' + str(int(mean(readLengths))) + '/' + str(int(amax(readLengths)))) self.reportResults('Q-Score (Min/Avg/Max): ' + str(int(amin(readQualities))) + '/' + str(int(mean(readQualities))) + '/' + str(int(amax(readQualities))) + '\n') if ('length_rejected' in preparedReadResults.keys()): readLengths = preparedReadResults['length_rejected'][0] readQualities = preparedReadResults['length_rejected'][1] self.reportResults('Length-Reject Reads') self.reportResults(str(len(readLengths)) + ' reads were rejected for improper length.') self.reportResults('Length (Min/Avg/Max): ' + str(int(amin(readLengths))) + '/' + str(int(mean(readLengths))) + '/' + str(int(amax(readLengths)))) self.reportResults('Q-Score (Min/Avg/Max): ' + str(int(amin(readQualities))) + '/' + str(int(mean(readQualities))) + '/' + str(int(amax(readQualities))) + '\n') if ('quality_rejected' in preparedReadResults.keys()): readLengths = preparedReadResults['quality_rejected'][0] readQualities = preparedReadResults['quality_rejected'][1] self.reportResults('Quality-Reject Reads') self.reportResults(str(len(readLengths)) + ' reads were rejected for improper quality.') self.reportResults('Length (Min/Avg/Max): ' + str(int(amin(readLengths))) + '/' + str(int(mean(readLengths))) + '/' + str(int(amax(readLengths)))) self.reportResults('Q-Score (Min/Avg/Max): ' + str(int(amin(readQualities))) + '/' + str(int(mean(readQualities))) + '/' + str(int(amax(readQualities))) + '\n') else: raise Exception ('There is no all_reads category in the read results. This is unexpected, why?') def constructInitialReadStats(self): self.recordAnalysisStep('Step 1.) Calculating initial read stats') self.disableGUI() # Set the input and output directories self.assignIODirectories() writeConfigurationFile() # Run nit-picker for output directory # TODO: fix these parameters, especially sample ID. # TODO: RUn this in a thread, so the GUI can update. preparedReadsOutputDirectory = join(getConfigurationValue('output_directory'), '1_prepared_reads') #if(self.demultiplexReads): # sampleID = 'READS' #else: # sampleID = 'READS' # TODO: I am always using the leaf directory name. Does this work for multiplexed and demultiplexed samples? #self.inputDirectoryText.set(currentInputDirectory) #parentDir = abspath(join(currentInputDirectory, os.pardir)) leafDirName = basename(normpath(self.inputDirectoryText.get())) sampleID = leafDirName # suggestedOutputDirectory = join(parentDir,leafDirName + '_analysis') if not exists(preparedReadsOutputDirectory): makedirs(preparedReadsOutputDirectory) # preparedReadResults is a dictionary. # The result will have 2 arrays # readstats is a 2d array, with lengths and qualities. preparedReadResults = None # If demultiplex option is set to 1, demultiplex is "on". if (getConfigurationValue('demultiplex_reads') == '1'): barcodeFilePath = getBarcodeFilePath() preparedReadResults = prepareReads(getConfigurationValue('input_directory') , preparedReadsOutputDirectory , sampleID , barcodeFilePath , None # Reference File, we don't have one. , int(getConfigurationValue('min_length')) , int(getConfigurationValue('max_length')) , int(getConfigurationValue('min_quality')) , int(getConfigurationValue('max_quality')) , False) else: preparedReadResults = prepareReads(getConfigurationValue('input_directory') , preparedReadsOutputDirectory , sampleID , None # No Barcoding file. , None # No Allele Reference , int(getConfigurationValue('min_length')) , int(getConfigurationValue('max_length')) , int(getConfigurationValue('min_quality')) , int(getConfigurationValue('max_quality')) , False) self.reportReadStats(preparedReadResults) self.recordAnalysisStep('Done calculating initial read stats') self.enableGUI() def sortByLocus(self): self.recordAnalysisStep('Step 2.) Sort reads by HLA Locus') self.disableGUI() # TODO: What if it's demultiplexed? # I should sort each barcode. # Make a loop, find barcodes, sort each one in a subrdirectory # What if i use some other sample ID, other than READS # TODO: Look for fastq files dynamically in output directory. #sampleID = 'READS' # TODO: I need to rethink how to handle sampleID when I am demultiplexing. # I can handle one sample one folder. # TODO: threadCount should be a parameter somewhere. # Specified in the options, probably. threadCount = 4 #preparedReadsInputFile = join(join(self.outputDirectoryText.get(), '1_prepared_reads'),sampleID + '_Pass.fastq') preparedReadsInput = join(self.outputDirectoryText.get(), '1_prepared_reads') #sortedReadsOutputDirectory = join(join(self.outputDirectoryText.get(), '2_sorted_reads'), sampleID) sortedReadsOutputDirectory = join(self.outputDirectoryText.get(), '2_sorted_reads') if not exists(sortedReadsOutputDirectory): makedirs(sortedReadsOutputDirectory) # TODO: Make more than one gene references. Split by locus. # Fine. That's what I'm doing. # Make a list of the reference files I need. referenceFileList = [] print('the configuration value for analyze_hla_a is:' + str(getConfigurationValue('analyze_hla_a'))) if(str(getConfigurationValue('analyze_hla_a')) == '1'): referenceFileList.append(getBlastSortResourceLocation('HLA_A_BlastReference.fasta')) if(str(getConfigurationValue('analyze_hla_b')) == '1'): referenceFileList.append(getBlastSortResourceLocation('HLA_B_BlastReference.fasta')) if(str(getConfigurationValue('analyze_hla_c')) == '1'): referenceFileList.append(getBlastSortResourceLocation('HLA_C_BlastReference.fasta')) if(str(getConfigurationValue('analyze_hla_e')) == '1'): referenceFileList.append(getBlastSortResourceLocation('HLA_E_BlastReference.fasta')) if(str(getConfigurationValue('analyze_hla_dra')) == '1'): referenceFileList.append(getBlastSortResourceLocation('HLA_DRA_BlastReference.fasta')) if(str(getConfigurationValue('analyze_hla_dqa1')) == '1'): referenceFileList.append(getBlastSortResourceLocation('HLA_DQA1_BlastReference.fasta')) if(str(getConfigurationValue('analyze_hla_dqb1')) == '1'): referenceFileList.append(getBlastSortResourceLocation('HLA_DQB1_BlastReference.fasta')) if(str(getConfigurationValue('analyze_hla_drb1')) == '1'): referenceFileList.append(getBlastSortResourceLocation('HLA_DRB1_BlastReference.fasta')) print('I found this many blast references:' + str(len(referenceFileList))) sortReferencePath = combineBlastReferences(referenceFileList, join(self.outputDirectoryText.get(), 'blast_sort_reference')) # the key is the name of the file analyzed. # The value is a list of minion_read_collections, pertaining to what gene they sorted to. sortResults = sortDirectory(preparedReadsInput, sortedReadsOutputDirectory, sortReferencePath, threadCount) # Report the BLAST sorting results in the results summary. self.reportResults('Read Sorting:\n') # Loop through the analyzed read files (probably just one here) for analyzedReadResult in sortResults.keys(): #print ('Looking at this read collection key:' + analyzedReadResult) blastGeneList = sortResults[analyzedReadResult] #print ('Looking at this list of sorted read groups\n:' + str(blastGeneList)) self.reportResults(analyzedReadResult + ':') # loop through each entry in this for genewiseSortedReadGroup in blastGeneList: if (genewiseSortedReadGroup.gene is None): self.reportResults('Unsorted: ' + str(len(genewiseSortedReadGroup.readCollection)) + ' reads.') else: self.reportResults('HLA-' + str(genewiseSortedReadGroup.gene) + ': ' + str(len(genewiseSortedReadGroup.readCollection)) + ' reads.') self.reportResults('') self.recordAnalysisStep('Done sorting reads by HLA Locus') self.enableGUI() def assembleSortedReads(self): self.recordAnalysisStep('Step 3.) Assemble sorted Reads') self.disableGUI() self.reportResults('Read Assembly:\n') # TODO: Deal with sample IDs better. # What about demultiplexed samples etc? #sampleID = 'Pass_Reads' #sortedReadsOutputDirectory = join(join(self.outputDirectoryText.get(), '2_sorted_reads'), sampleID) #readAssemblyDirectory = join(join(self.outputDirectoryText.get(), '3_assembled_reads'), sampleID) sortedReadsOutputDirectory = join(self.outputDirectoryText.get(), '2_sorted_reads') readAssemblyDirectory = join(self.outputDirectoryText.get(), '3_assembled_reads') # Dictionary. Key is the location of the generated fasta consensus sequences. # Value is the # of reads represented in this consensus. readAssemblyResults = {} if not exists(readAssemblyDirectory): makedirs(readAssemblyDirectory) # for each barcode folder in this directory for sortedReadDirectoryObject in listdir(sortedReadsOutputDirectory): fullBarcodeDirPath = join(sortedReadsOutputDirectory,sortedReadDirectoryObject) # Should only be directories under here. # Either barcode directories, or a "pass" folder if (isfile(fullBarcodeDirPath)): raise Exception('There is a file in the sorted read output directory. I expected only barcode directories:' + str(sortedReadDirectoryObject)) elif (isdir(fullBarcodeDirPath)): # We found a barcode folder. I should assemble the fastq files in here. #self.recordAnalysisStep('Assembling reads in this directory:' + fullBarcodeDirPath) # Do not assemble the "All Reads" directory, waste of time. # TODO: How should this work? Make sure this makes sense when I am debarcoding this. # TODO: I dont think this is working at all. All_Reads is not used? if('All_Reads' not in fullBarcodeDirPath): logMessageToFile('Assembling this directory:' + str(fullBarcodeDirPath)) for currentReadFileName in listdir(fullBarcodeDirPath): # Only fastq files # Also, skip assembling the unsorted reads. if(".fastq"== currentReadFileName[-6:] or ".fq" == currentReadFileName[-3:]): currentReadFilePath = join(fullBarcodeDirPath, currentReadFileName) currentAssemblyOutputDirectory = join(join(readAssemblyDirectory, sortedReadDirectoryObject),currentReadFileName) # TODO: This will cause problems. Sometimes I WANT to assemble unsorted reads. if('unsorted_' in currentReadFileName): self.recordAnalysisStep('Skip assembly of these unsorted reads:' + str(currentReadFilePath)) else: self.recordAnalysisStep('Assembling these reads:' + str(currentReadFilePath)) # TODO Parameters numberIterations = 6 numberThreads = 4 splitHeterozygotes = True #_(self, readsFile, outputDir, referenceFile, numIters, numThreads, splitHeterozygotes, snps ): myAlleleWrangler = AlleleWrangler(currentReadFilePath, currentAssemblyOutputDirectory, None, numberIterations, numberThreads, splitHeterozygotes, None) currentAssemblyResults = myAlleleWrangler.analyzeReads() #Merge into completed results for key in currentAssemblyResults.keys(): readAssemblyResults[key] = currentAssemblyResults[key] else: logMessageToFile('Skipping assembly on this directory:' + str(fullBarcodeDirPath)) pass else: raise Exception('This object is neither a file or directory. How mysterious. I expected only barcode directories:' + str(fullBarcodeDirPath)) # Gather each fasta consensus sequence and write it to a summary.fasta file. consensusSequences = [] #self.reportResults('AssemblyResults:\n' + str(readAssemblyResults)) for index, key in enumerate(readAssemblyResults.keys()): readCount = readAssemblyResults[key] self.reportResults('Consensus Sequence: ' + str(key)) self.reportResults(str(readCount) + ' reads represented in this assembly.\n') # Read sequence from assembly fasta currentConsensusSeq = list(parseReads(key, 'fasta'))[0] currentConsensusSeq.id = 'Consensus_Sequence_' + str(index + 1) currentConsensusSeq.description = 'Read_Count=' + str(readCount) # Add sequence to list consensusSequences.append(currentConsensusSeq) # Write out one fasta with all consensus sequences. combinedConsensusOutputFilename = join(self.outputDirectoryText.get(), 'Consensus_Sequences.fasta') sequenceWriter = createOutputFile(combinedConsensusOutputFilename) write(consensusSequences, sequenceWriter, 'fasta') sequenceWriter.close() self.recordAnalysisStep('Done assembling sorted Reads') self.enableGUI() def alleleCall(self): self.recordAnalysisStep('Step 4.) HLA Allele Calling') self.disableGUI() self.recordAnalysisStep('Just kidding. This feature must be implemented') self.recordAnalysisStep('Done with HLA Allele Calling') self.enableGUI() def summarizeResults(self): self.recordAnalysisStep('Step 5.) Summarize Results') self.disableGUI() self.recordAnalysisStep('Just kidding. This feature must be implemented') self.recordAnalysisStep('Done Summarizing Results') self.enableGUI() # chooseReadInputDirectory method is called when the user presses the input directory button def chooseReadInputDirectory(self): print ('Choosing an input directory.') # TODO: What happens when I cancel this? I need to re-enable the GUI. self.disableGUI() self.setInputDir(filedialog.askdirectory(**self.dir_opt), True) self.enableGUI() # chooseReadInputDirectory method is called when the user presses the input directory button def chooseReadOutputDirectory(self): print ('Choosing an output directory.') self.disableGUI() self.setOutputDir(filedialog.askdirectory(**self.dir_opt)) self.enableGUI() def setInputDir(self, currentInputDirectory, setOutputDir): # setInputDir is a subprocess to be called when an input directory is selected. self.inputDirectoryText.set(currentInputDirectory) #print ('Just set the self.inputDirectory text to this:' + self.inputDirectoryText.get()) # TODO: Is there at least one fastq file in this directory? It has reads? # If not, this might be a directory of pre-demultiplexed reads. # TODO: Do I need to parse subfolders for any reason? I think not. # TODO: In the case of pre-demultiplexed reads, maybe. # Popup, Should I use the suggested output directory? # Include a boolean, in case i don't want to mess with output directory yet. if setOutputDir: parentDir = abspath(join(currentInputDirectory, pardir)) leafDirName = basename(normpath(currentInputDirectory)) suggestedOutputDirectory = join(parentDir,leafDirName + '_analysis') queryResult = messagebox.askquestion('Use Suggested Output Directory?' , 'Use this output directory?\n' + suggestedOutputDirectory + '\nSelect No to choose your own output directory', icon='warning') if queryResult == 'yes': self.setOutputDir(suggestedOutputDirectory) else: self.chooseReadOutputDirectory() # If Yes, Do it # If no, call chooseReadOutputDirectory def setOutputDir(self, currentOutputDirectory): self.outputDirectoryText.set(currentOutputDirectory) # This output directory should exist if not exists(currentOutputDirectory): makedirs(currentOutputDirectory)
class myToolbox: def __init__(self, master): # ~ self.adw = adawat.adawat.Adawat() # opend file self.filename = "" # parser self.parser = tm.html_displayer() self.master = master master.title(u"جدول التوقيت TimeTable ") myfont = os.path.join(sys.path[0], "resources", "fonts", "AmiriTypewriter-Regular.ttf") self.total = 0 self.entered_number = 0 # make menu self.makemenu() # ~ self.output_label = Label(master, text="Output") self.shape_label = Label(master, text="Shape") self.label = Label(master, text="Output:") self.label_actions = Label(master, text="Action:") self.label_config = Label(master, text="Config:") #~ vcmd = master.register(self.validate) # we have to wrap the command #self.entry = Text(master, height=15, width=70, font=myfont) # ~ self.output = Text(master, height=15, width=70, font=myfont) self.output = HTMLScrolledText(master, height=15, width=70, font=myfont) # ~ sampletext = u"""Greating\tالسلام عليكم ورحمة الله وبركاته # ~ Welcome\tمرحبا\tBien venue # ~ Welcome\tأهلا ووسهلا""" # ~ self.entry.insert("1.0", self.bidi(sampletext)) #~ self.nshape = Entry(master, validate="key") #~ self.nshape.insert(END,2) #~ self.entry = Entry(master, validate="key", validatecommand=(vcmd, '%P')) self.freerooms_button = Button( master, text="Free Rooms", command=lambda: self.update("freerooms")) self.availteachers_button = Button( master, text="Available Teachers", command=lambda: self.update("teachers")) self.timetable_button = Button( master, text="TimeTable", command=lambda: self.update("timetables")) # ~ self.reshape_button = Button(master, text="Reshape", command=lambda: self.update("reshape")) # ~ self.itemize_button = Button(master, text="Itemize", command=lambda: self.update("itemize")) self.affectation_button = Button( master, text="Affectation", command=lambda: self.update("affectation")) self.charge_button = Button(master, text="Charges", command=lambda: self.update("charges")) # ~ self.list_button = Button(master, text="Python list", command=lambda: self.update("pythonlist")) # ~ self.tabbing_button = Button(master, text="Tabbing", command=lambda: self.update("tabbing")) self.submit_button = Button(master, text="Submit", bg="green", fg="white", command=lambda: self.update("submit")) self.reset_button = Button(master, text="Reset", command=lambda: self.update("reset")) self.copy_button = Button(master, text="Copy", command=lambda: self.update("copy")) self.recopy_button = Button(master, text="Recopy", command=lambda: self.update("recopy")) #format options OPTIONS_ROOMS = ["all", "tp", "salle"] self.rooms_opt = StringVar() self.rooms_opt.set(OPTIONS_ROOMS[0]) self.rooms_options = OptionMenu(master, self.rooms_opt, *OPTIONS_ROOMS) #language options OPTIONS = ["all", "vac", "tp", "cours", "details"] self.teacher_opt = StringVar() self.teacher_opt.set(OPTIONS[0]) self.teacher_options = OptionMenu(master, self.teacher_opt, *OPTIONS) # ~ # shape options # ~ OPTIONS_SHAPE = [1,2,3,4,5,6,7,8,9] # ~ self.shape_opt = IntVar() # ~ self.shape_opt.set(OPTIONS_SHAPE[2]) # ~ self.shape_options = OptionMenu(master, self.shape_opt, *OPTIONS_SHAPE) # transliterate OPTIONS_TM = ["groups", "teachers", "rooms"] self.tm_opt = StringVar() self.tm_opt.set(OPTIONS_TM[0]) self.tm_options = OptionMenu(master, self.tm_opt, *OPTIONS_TM) # ~ # itemize options # ~ OPTIONS_ITEM = ["itemize","enumerate"] # ~ self.itemize_opt = StringVar() # ~ self.itemize_opt.set(OPTIONS_ITEM[0]) # ~ self.itemize_options = OptionMenu(master, self.itemize_opt, *OPTIONS_ITEM) # ~ # separator options # ~ OPTIONS_SEP= ["tab", "space", ";",",", "\\t"] # ~ self.separator_opt = StringVar() # ~ self.separator_opt.set(OPTIONS_SEP[0]) # ~ self.separator_options = OptionMenu(master, self.separator_opt, *OPTIONS_SEP) # Actions options OPTIONS_ACTION = self.parser.commands self.action_opt = StringVar() self.action_opt.set(OPTIONS_ACTION[0]) self.action_options = OptionMenu(master, self.action_opt, *OPTIONS_ACTION) # LAYOUT #0 self.label.grid(row=0, column=0, sticky=W) self.label_actions.grid(row=0, column=3, sticky=W) self.label_config.grid(row=0, column=4, sticky=W) #1 self.output.grid(row=1, column=0, rowspan=6, columnspan=3, sticky=W + E) # ~ self.entry.grid(row=1, column=0, rowspan=6, columnspan=3, sticky=W+E) #1 self.timetable_button.grid(row=1, column=3, sticky=W + E) self.tm_options.grid(row=1, column=4, sticky=W + E) #2 self.freerooms_button.grid(row=2, column=3, sticky=W + E) self.rooms_options.grid(row=2, column=4, sticky=W + E) #3 self.availteachers_button.grid(row=3, column=3, sticky=W + E) self.teacher_options.grid(row=3, column=4, sticky=W + E) # ~ #3 # ~ self.timetable_button.grid(row=3, column=3, sticky=W+E) # ~ self.tm_options.grid(row=3, column=4, sticky=W+E) #4 self.affectation_button.grid(row=4, column=3, sticky=W + E) self.charge_button.grid(row=4, column=4, sticky=W + E) # ~ self.reshape_button.grid(row=5, column=3, sticky=W+E) # ~ self.shape_options.grid(row=5, column=4, sticky=W+E) # ~ #6 # ~ self.itemize_button.grid(row=6, column=3, sticky=W+E) # ~ self.itemize_options.grid(row=6, column=4, sticky=W+E) #7 Output label # ~ self.output_label.grid(row=7, column=0, columnspan=1, sticky=W) self.submit_button.grid(row=7, column=1, sticky=E) self.action_options.grid(row=7, column=2, sticky=W + E) # ~ self.tabbing_button.grid(row=7, column=3, sticky=W+E) # ~ self.separator_options.grid(row=7, column=4, sticky=W+E) # 8 # ~ self.output.grid(row=8, column=0, rowspan=6, columnspan=3, sticky=W+E) # 9 # ~ self.list_button.grid(row=9, column=4, sticky=W+E) #10 self.copy_button.grid(row=5, column=3, columnspan=2, sticky=W + E) self.recopy_button.grid(row=6, column=3, columnspan=2, sticky=W + E) self.reset_button.grid(row=7, column=3, columnspan=2, sticky=W + E) #5 def makemenu(self, ): menubar = Menu(self.master) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label="New", command=donothing) filemenu.add_command(label="Open", command=self.browseFiles) filemenu.add_command(label="Save", command=donothing) filemenu.add_command(label="Save as...", command=donothing) filemenu.add_command(label="Close", command=donothing) filemenu.add_separator() filemenu.add_command(label="Exit", command=self.master.quit) menubar.add_cascade(label="File", menu=filemenu) editmenu = Menu(menubar, tearoff=0) editmenu.add_command(label="Undo", command=donothing) editmenu.add_separator() editmenu.add_command(label="Cut", command=donothing) editmenu.add_command(label="Copy", command=lambda: self.update("copy")) editmenu.add_command(label="ReCopy", command=lambda: self.update("recopy")) editmenu.add_command(label="Paste", command=donothing) editmenu.add_command(label="Delete", command=lambda: self.update("reset")) editmenu.add_command(label="Select All", command=donothing) menubar.add_cascade(label="Edit", menu=editmenu) # Available menu latexmenu = Menu(menubar, tearoff=0) latexmenu.add_command(label="Free rooms", command=lambda: self.update("freerooms")) latexmenu.add_command(label="Available teachers", command=lambda: self.update("teachers")) latexmenu.add_command( label="Available teachers TP", command=lambda: self.update("availableteachers_tp")) latexmenu.add_command( label="Available teachers vacataires", command=lambda: self.update("availableteachers_vac")) latexmenu.add_command( label="Available teachers Details", command=lambda: self.update("availableteachers_details")) menubar.add_cascade(label="Available", menu=latexmenu) # Time Table arabicmenu = Menu(menubar, tearoff=0) arabicmenu.add_command( label="TimeTable by group", command=lambda: self.update("timetables_groups")) arabicmenu.add_command( label="Language by teachers", command=lambda: self.update("timetables_teachers")) arabicmenu.add_command(label="Language by rooms", command=lambda: self.update("timetables_rooms")) menubar.add_cascade(label="TimeTables", menu=arabicmenu) # Charges toolsmenu = Menu(menubar, tearoff=0) toolsmenu.add_command(label="Charges", command=lambda: self.update("charges")) toolsmenu.add_command(label="Affectation", command=lambda: self.update("affectation")) menubar.add_cascade(label="Charges", menu=toolsmenu) helpmenu = Menu(menubar, tearoff=0) helpmenu.add_command(label="Help Index", command=lambda: self.update("help")) helpmenu.add_command(label="About...", command=lambda: self.update("about")) menubar.add_cascade(label="Help", menu=helpmenu) self.master.config(menu=menubar) # Function for opening the # file explorer window def browseFiles(self, ): self.filename = filedialog.askopenfilename( initialdir="¬", title="Select a File", filetypes=(("Text files", "*.oct*"), ("all files", "*.*"))) # Change label contents # ~ label_file_explorer.configure(text="File Opened: "+filename) #~ @staticmethod print("filename :", self.filename) self.parser = tm.html_displayer(self.filename) # default self.update("default") def bidi(self, text): return text #~ reshaped_text = self.adw.delimite_language_bidi(text, arabic_reshaper.reshape) #~ reshaped_text = arabic_reshaper.reshape(text) #~ bidi_text = get_display(reshaped_text) #~ return bidi_text #~ @staticmethod def unbidi(self, text): return text #~ unshaped_text = pyarabic.unshape.unshaping_text(text) #~ unshaped_text = self.adw.delimite_language_bidi(text, pyarabic.unshape.unshaping_text) #~ bidi_text = get_display(reshaped_text) #~ return unshaped_text # ~ def get_separator(self,): # ~ sep = self.separator_opt.get() # ~ if sep =="tab": # ~ return "\t" # ~ elif sep =="space": # ~ return " " # ~ else: # ~ return sep def help(self): tkMessageBox.showinfo("Help", "Not yet implemented") def about(self): tkMessageBox.showinfo( "Help", self.bidi(u"TimeTable from OpenOCTT\ndeveloped by Taha Zerrouki")) def update(self, method): """ """ if not self.filename: tkMessageBox.showinfo("Info", "You should select a timetable file") return False display_format = self.rooms_opt.get() if method == "help": self.help() return True if method == "about": self.about() return True if method == "reset": self.output.delete("1.0", END) # ~ self.entry.delete("1.0", END) return True if method == "recopy": result = self.output.get("1.0", END) # ~ self.entry.delete("1.0", END) # ~ self.entry.insert("1.0", result) return True if method == "copy": value = self.output.get("1.0", END) self.master.clipboard_clear() self.master.clipboard_append(self.unbidi(value)) return True if method == "submit": command = self.action_opt.get() #~ print(command) else: command = method # ~ value = self.entry.get("1.0",END) #value = self.unbidi(value) if command == "default": command = "timetables_groups" if command == "freerooms": room_type = self.rooms_opt.get() if room_type and room_type != "all": command += "_" + room_type result = self.parser.action(command) elif command == "teachers": command = "availableteachers" teacher_type = self.teacher_opt.get() if teacher_type and teacher_type != "all": command += "_" + teacher_type result = self.parser.action(command) elif command == "timetables": slot_type = self.tm_opt.get() if slot_type and slot_type != "all": command += "_" + slot_type result = self.parser.action(command) elif command == "affectation": result = self.parser.action(command) elif command == "charges": result = self.parser.action(command) elif command in self.parser.commands: result = self.parser.action(command) else: # reset donothing() result = "Nothing to do with %s" % command self.output.delete("1.0", END) # ~ self.output.insert("1.0", self.bidi(result)) self.output.set_html(result)
class MainUI(): def __init__(self, root): self.notify_queue = queue.Queue() self.gress_bar_init_history = GressBar() self.gress_bar_verify_user = GressBar() self.root = root self.top = None self._is_user_valid = False self._user_info = {} self._strategy_dict = {} root.title("Huobi Trade") log_config.init_log_config(use_mail=False) self._hb = None self._strategy_pool = StrategyPool() # self.ckb_macd_val = IntVar() # self.ckb_macd = Checkbutton(root, text='MACD', variable=self.ckb_macd_val, onvalue=1, offvalue=0, command=self.call_ckb_macd).pack() # self.label = Label(root, text="This is our first GUI!") # self.label.pack() # # self.init_history_button = Button(root, text="Init History", command=self.init_history, width=20) # self.start_button = Button(root, text="Start Work", command=self.start_work, width=20) # self.start_button.pack() self.stop_button = Button(root, text="Stop Work", command=self.stop_work, width=20) # self.stop_button.pack() self.register_button = Button(root, text="Register Strategy", command=self.register_strategy, width=20) # self.register_button.pack() self.start_check_strategy_button = Button(root, text="Start Check Strategy", command=self.start_check_strategy, width=20) # self.start_check_strategy_button.pack() self.stop_check_strategy_button = Button(root, text="Stop Check Strategy", command=self.stop_check_strategy, width=20) # self.stop_check_strategy_button.pack() self.clean_st_button = Button(root, text="Clean Strategy", command=self.clean_strategy, width=20) # self.clean_st_button.pack() self.verify_identity_button = Button(root, text="Verify Identity", command=self.set_up_config, width=20) self.init_history_button = Button(root, text="Init History", command=self.init_history_asyn, width=20) self.strategy_setting_button = Button(root, text="Strategy Config", command=self.set_up_strategy, width=20) self.label_pop = Label(root, text="POP: ", width=5) self.price_text = StringVar() self.price_text.set("") self.price_label = Label(root, textvariable=self.price_text, foreground='red', background="gray", font=("", 14, 'bold'), width=22) # self.price_label.pack() self.label_bal = Label(root, text="Balance: ", width=7) self.bal_text = StringVar() self.bal_text.set("") self.bal_label = Label(root, textvariable=self.bal_text, foreground='red', background="gray", font=("", 14, 'bold'), width=40) self.label_coin = Label(root, text="Total: ", width=5) self.coin_text = StringVar() self.coin_text.set("") self.coin_label = Label(root, textvariable=self.coin_text, foreground='red', background="gray", font=("", 14, 'bold'), width=22) self.label_profit = Label(root, text="Profit: ", width=7) self.profit_text = StringVar() self.profit_text.set("") self.profit_label = Label(root, textvariable=self.profit_text, foreground='red', background="gray", font=("", 14, 'bold'), width=30) self.clean_profit_button = Button(root, text="Clean", command=self.clean_profit, width=10) # row6 = Frame(root) # row6.pack(fill="x", ipadx=1, ipady=1) self.label_kdj = Label(root, text="K/D/J: ", width=6) self.kdj_text = StringVar() self.kdj_text.set("") self.kdj_label = Label(root, textvariable=self.kdj_text, foreground='red', background="gray", font=("", 12, 'bold'), width=20) self.label_uml = Label(root, text="U/M/L: ", width=6) self.uml_text = StringVar() self.uml_text.set("") self.uml_label = Label(root, textvariable=self.uml_text, foreground='red', background="gray", font=("", 12, 'bold'), width=50) # self.label_worth = Label(root, text="Worth: ", width=5) # self.worth_text = StringVar() # self.worth_text.set("Worth") # self.worth_label = Label(root, textvariable=self.worth_text, foreground='blue', background="gray", # font=("", 14, 'bold'), width=12) self.label_run_log = Label(root, text="run log: ", width=10) self.log_text = ScrolledText(root, width=60, height=26) self.label_trade_log = Label(root, text="trade log: ", width=10) self.trade_text = ScrolledText(root, width=60, height=26) # self.log_text.pack() # 创建一个TAG,其前景色为红色 self.log_text.tag_config('BUY', foreground='green', background="orange", font=("", 11, 'bold')) self.log_text.tag_config('SELL', foreground='red', background="orange", font=("", 11, 'bold')) self.log_text.tag_config('WARNING', foreground='orange') self.log_text.tag_config('ERROR', foreground='red') self.log_text.tag_config('EXCEPTION', foreground='red') self.log_text.tag_config('CRITICAL', background="red") self.log_text.tag_config('SHOW', foreground='green', font=("", 11, 'bold')) self.log_text.see(END) self.trade_text.tag_config('BUY', foreground='green', background="orange", font=("", 11, 'bold')) self.trade_text.tag_config('SELL', foreground='red', background="orange", font=("", 11, 'bold')) self.log_text.see(END) self.verify_identity_button.grid(row=0, column=0) self.init_history_button.grid(row=1, column=0) self.start_button.grid(row=2, column=0) self.strategy_setting_button.grid(row=3, column=0) self.register_button.grid(row=4, column=0) self.start_check_strategy_button.grid(row=5, column=0) self.clean_st_button.grid(row=6, column=0) self.stop_check_strategy_button.grid(row=7, column=0) self.stop_button.grid(row=8, column=0) self.label_pop.grid(row=0, column=1) self.price_label.grid(row=0, column=2) self.label_bal.grid(row=0, column=3) self.bal_label.grid(row=0, column=4, columnspan=2) self.label_coin.grid(row=1, column=1) self.coin_label.grid(row=1, column=2) # self.label_worth.grid(row=0, column=7) # self.worth_label.grid(row=0, column=8) self.label_profit.grid(row=1, column=3) self.profit_label.grid(row=1, column=4) self.clean_profit_button.grid(row=1, column=5) # k d 指标位置 # row6.grid(row=2, column=1) self.label_kdj.grid(row=2, column=1) self.kdj_label.grid(row=2, column=2) self.label_uml.grid(row=2, column=3) self.uml_label.grid(row=2, column=4, columnspan=2) self.label_run_log.grid(row=3, column=1) self.log_text.grid(row=4, column=1, rowspan=5, columnspan=3) self.label_trade_log.grid(row=3, column=4) self.trade_text.grid(row=4, column=4, rowspan=5, columnspan=3) self.start_button.config(state="disabled") self.register_button.config(state="disabled") self.stop_button.config(state="disabled") self.clean_st_button.config(state="disabled") self.stop_check_strategy_button.config(state="disabled") self.start_check_strategy_button.config(state="disabled") self.init_history_button.config(state="disabled") def init_history_asyn(self): def init_history(hb): ret = self._hb.init() # 这一步是必须的,先同步处理 ret2 = hb.init_history() self.gress_bar_init_history.quit() if not (ret and ret2): logger.error("init service failed.") log_config.output2ui("init service failed.", 3) messagebox.showwarning("Error", "init history data failed.") return False log_config.output2ui("Init history data successfully!", 8) self.start_button.config(state="normal") self.register_button.config(state="normal") self.init_history_button.config(state="disabled") huobi.save_history_trade_vol(config.NEED_TOBE_SUB_SYMBOL) if not self._hb: self._hb = Huobi() th = threading.Thread(target=init_history, args=(self._hb,)) th.setDaemon(True) th.start() self.gress_bar_init_history.start() return True def start_work(self): def start(hb): logger.info("start work!!") log_config.output2ui("start work!!", 1) hb.run() logger.warning("work over!!") log_config.output2ui("work over!!", 2) if not self._hb: self._hb = Huobi() th = threading.Thread(target=start, args=(self._hb,)) th.setDaemon(True) th.start() self.stop_button.config(state="normal") self.start_button.config(state="disabled") self.start_check_strategy_button.config(state="normal") self.verify_identity_button.config(state="disabled") def stop_work(self): logger.info("stop_work!") log_config.output2ui("stop_work!") if self._hb: self._hb.exit() self.stop_check_strategy() self.stop_button.config(state="disabled") self.start_button.config(state="normal") self.register_button.config(state="normal") self.start_check_strategy_button.config(state="disabled") # self.verify_identity_button.config(state="normal") self.init_history_button.config(state="normal") self.verify_identity_button.config(state="normal") log_config.output2ui("Stop work successfully!", 8) def start_check_strategy(self): # 策略检测线程启动 logger.info("start_check_strategy...") log_config.output2ui("start_check_strategy...") self._strategy_pool.start_work() self.start_check_strategy_button.config(state="disabled") self.stop_check_strategy_button.config(state="normal") log_config.output2ui("Start check strategy successfully!", 8) def stop_check_strategy(self): logger.warning("stop_check_strategy...") log_config.output2ui("stop_check_strategy...", 2) self._strategy_pool.stop_work() self.start_check_strategy_button.config(state="normal") self.stop_check_strategy_button.config(state="disabled") log_config.output2ui("Stop check strategy successfully!", 8) def register_strategy(self): logger.info("register_strategy.") log_config.output2ui("register_strategy.") self._strategy_pool.clean_all() for strategy in strategies.STRATEGY_LIST: logger.info("register_strategy, strategy={}".format(strategy.name)) log_config.output2ui("register_strategy, strategy={}".format(strategy.name)) self._strategy_pool.register(strategy) self.clean_st_button.config(state="normal") self.register_button.config(state="disabled") log_config.output2ui("Register strategy successfully!", 8) def clean_strategy(self): logger.warning("clean_strategy...") log_config.output2ui("clean_strategy...", 2) self._strategy_pool.clean_all() self.clean_st_button.config(state="disabled") self.register_button.config(state="normal") log_config.output2ui("Clean strategy successfully!", 8) # def call_ckb_macd(self): # print("check macd val=%d" % self.ckb_macd_val.get()) def center_window(self, width, height): screenwidth = self.root.winfo_screenwidth() screenheight = self.root.winfo_screenheight() size = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2) self.root.geometry(size) def update_coin(self, price=None): try: if not price: price_text = self.price_text.get() price = 0 if len(price_text.split(":")) > 1: price = float(price_text.split(":")[1]) else: price = 0 else: price = float(price) bal_text = self.bal_text.get() coin_str = bal_text.split(",")[0].split(":")[1].split("/") dollar_str = bal_text.split(",")[1].split(":")[1].split("/") if len(coin_str) > 0 and len(dollar_str) > 0: coin_trade = float(coin_str[0]) coin_frozen = float(coin_str[1]) dollar_trade = float(dollar_str[0]) dollar_frozen = float(dollar_str[1]) total_coin_value = round(coin_trade + coin_frozen + (dollar_trade + dollar_frozen) / price, 3) total_dollar_value = round((coin_trade + coin_frozen) * price + dollar_trade + dollar_frozen, 3) self.coin_text.set("{}/{}".format(total_coin_value, total_dollar_value)) if not process.ORG_COIN: process.ORG_COIN = total_coin_value process.ORG_DOLLAR = total_dollar_value profit_coin = round(total_coin_value - process.ORG_COIN, 3) profit_dollar = round(total_dollar_value - process.ORG_DOLLAR, 3) self.profit_text.set("{}/{}".format(profit_coin, profit_dollar)) except Exception as e: pass # logger.exception("update_coin e={}".format(e)) def update_ui(self): # # 每1000毫秒触发自己,形成递归,相当于死循环 # self.root.after(1000, self.process_msg) logger.info("Welcome to Huobi Trade Tool") log_config.output2ui("Welcome to Huobi Trade Tool", 8) log_config.output2ui("Please Click [Verify Identity] to authenticate", 8) def update_price(price_text): while True: try: msg = process.REALTIME_PRICE.get(block=True) # print("update_price {}".format(msg)) (key, value), = msg.items() global CURRENT_PRICE CURRENT_PRICE = float(value) price_text.set("{}:{}".format(key.upper(), value)) self.update_coin(price=value) except Exception as e: logger.exception("update_price exception....") log_config.output2ui("update_price exception....", 3) continue def update_balance(bal_text): while True: try: msg = process.REALTIME_BALANCE.get(block=True) bal_text.set(str(msg)) except Exception as e: logger.exception("update_balance exception....") log_config.output2ui("update_balance exception....", 3) continue def update_ui_log(log_text, trade_text): while True: try: if not log_config.REALTIME_LOG.empty(): msg_dict = log_config.REALTIME_LOG.get(block=True) if msg_dict["level"] == "BUY" or msg_dict["level"] == "SELL": trade_text.configure(state='normal') trade_text.insert(END, msg_dict["msg"], msg_dict["level"]) trade_text.see(END) trade_text.configure(state='disabled') else: log_text.configure(state='normal') log_text.insert(END, msg_dict["msg"], msg_dict["level"]) log_text.see(END) log_text.configure(state='disabled') except Exception as e: logger.exception("update_ui_log exception....") log_config.output2ui("update_ui_log exception....", 3) continue def update_kdj(kdj_text): while True: try: kdj = process.REALTIME_KDJ.get(block=True) self.kdj_text.set("{}/{}/{}".format(round(kdj[0], 2), round(kdj[1], 2), round(kdj[2], 2))) except Exception as e: logger.exception("update_kdj exception....") log_config.output2ui("update_kdj exception....", 3) def update_uml(uml_text): while True: try: global CURRENT_PRICE uml = process.REALTIME_UML.get(block=True) diff1 = uml[0] - uml[1] diff2 = uml[1] - uml[2] uml_text.set("{}/{}/{}-{}/{}-{}/{}".format(round(uml[0], 3), round(uml[1], 3), round(uml[2], 3), round(diff1, 3), round(diff2, 3), round(diff1 / CURRENT_PRICE, 4), round(diff2 / CURRENT_PRICE, 4))) except Exception as e: logger.exception("update_uml exception....") log_config.output2ui("update_uml exception....", 3) th = threading.Thread(target=update_price, args=(self.price_text,)) th.setDaemon(True) th.start() th = threading.Thread(target=update_ui_log, args=(self.log_text, self.trade_text, )) th.setDaemon(True) th.start() th = threading.Thread(target=update_balance, args=(self.bal_text,)) th.setDaemon(True) th.start() th = threading.Thread(target=update_uml, args=(self.uml_text,)) th.setDaemon(True) th.start() th = threading.Thread(target=update_kdj, args=(self.kdj_text,)) th.setDaemon(True) th.start() return True def close_window(self): ans = askyesno("Warning", message="Are you sure to quit?") if ans: self.gress_bar_init_history.quit() self.gress_bar_verify_user.quit() self.stop_check_strategy() self.stop_work() self.root.destroy() else: return def verify_user_information(self): def verify_user_by_get_balance(currency, ak, sk, ws_site, rest_site, retry): from rs_util import HuobiREST config.CURRENT_WS_URL = config.WS_URLS[ws_site] config.CURRENT_REST_MARKET_URL = config.REST_URLS[rest_site][0] config.CURRENT_REST_TRADE_URL = config.REST_URLS[rest_site][1] hrs = HuobiREST(config.CURRENT_REST_MARKET_URL, config.CURRENT_REST_TRADE_URL, ak, sk, config.PRIVATE_KEY) hrs.get_accounts() # balance = strategies.get_balance( # currency, ak, sk, retry) # self.gress_bar_verify_user.quit() if hrs.account_id and hrs.account_state == config.ACCOUNT_STATE_WORKING: # if balance: self._is_user_valid = True config.ACCESS_KEY = self._user_info.get("access_key", None) config.SECRET_KEY = self._user_info.get("secret_key", None) config.NEED_TOBE_SUB_SYMBOL.clear() config.NEED_TOBE_SUB_SYMBOL.append(self._user_info.get("trade", None)) self._is_user_valid = True # self.verify_identity_button.config(state="disabled") self.init_history_button.config(state="normal") self.start_button.config(state="normal") strategies.update_balance(is_first=True) log_config.output2ui("Authentication passed!", 8) else: messagebox.showwarning("Error", "Authentication failed!") log_config.output2ui("Authentication failed!", 3) th = threading.Thread(target=verify_user_by_get_balance, args=( self._user_info.get("trade", None)[0:3], self._user_info.get("access_key", None), self._user_info.get("secret_key", None), self._user_info.get("ws_site", "BR"), self._user_info.get("rest_site", "BR"), 3,)) th.setDaemon(True) th.start() self.gress_bar_verify_user.start(text="Verifying user identity, please wait a moment...") def set_up_config(self): from popup_config import PopupConfig pop = PopupConfig(self._user_info, "Verify identity") self.root.wait_window(pop) if not self._user_info.get("ok", False): return logger.info("{}".format(self._user_info)) log_config.output2ui("{}".format(self._user_info)) self.price_text.set("") self.bal_text.set("") self.coin_text.set("") self.verify_user_information() # self.top = Toplevel(self.root) # label = Label(self.top, text="ACCESS_KEY") # label.pack() # entry = Entry(self.top) # entry.pack() # # btn = Button(self.top, text="OK") # btn.pack() def set_up_strategy(self): # from popup_trade import TradeStrategy # ret_data = {} # pop = TradeStrategy("wqrwqrqwrqwr", ret_data, 10) # self.root.wait_window(pop) # print(ret_data) from popup_strategy import PopupStrategy import strategies pop = PopupStrategy(strategies.move_stop_profit_params, strategies.stop_loss_params, strategies.kdj_buy_params, strategies.kdj_sell_params, strategies.vol_price_fly_params, strategies.boll_strategy_params, "Strategy config") self.root.wait_window(pop) print(strategies.kdj_buy_params) def clean_profit(self): process.ORG_COIN = None self.profit_text.set("0/0")
def youtube_dl_launcher_for_ffmpegaudioencoder(): # Imports---------------------------------------------------------------------------------------------------------- from tkinter import (filedialog, StringVar, Menu, E, W, N, S, LabelFrame, NORMAL, END, DISABLED, Checkbutton, Label, ttk, scrolledtext, messagebox, OptionMenu, Toplevel, WORD, Entry, Button, HORIZONTAL, SUNKEN, Text) import pyperclip, pathlib, threading, yt_dlp from re import sub from configparser import ConfigParser global main # --------------------------------------------------------------------------------------------------------- Imports # Main Gui & Windows ---------------------------------------------------------------------------------------------- def main_exit_function(): # Asks if the user is ready to exit confirm_exit = messagebox.askyesno( title='Prompt', message="Are you sure you want to exit the program?\n\n" " Note: This will end all current tasks!", parent=main) if confirm_exit: # If user selects Yes - destroy window main.destroy() # Main UI window -------------------------------------------------------------------------------------------------- try: # Checks rather or not the youtube-dl-gui window is already open if main is not None or Toplevel.winfo_exists(main): main.lift( ) # If youtube-dl-gui window exists then bring to top of all other windows except: # If youtube-dl-gui does not exist, create it... if not combined_with_ffmpeg_audio_encoder: from tkinter import Tk, PhotoImage main = Tk() # Make full tkinter loop if standalone main.iconphoto( True, PhotoImage(file="Runtime/Images/Youtube-DL-Gui.png")) if combined_with_ffmpeg_audio_encoder: main = Toplevel() # Make toplevel loop if NOT standalone main.title("Simple-Youtube-DL-Gui v1.21") main.configure(background="#434547") window_height = 500 window_width = 610 screen_width = main.winfo_screenwidth() screen_height = main.winfo_screenheight() x_coordinate = int((screen_width / 2) - (window_width / 2)) y_coordinate = int((screen_height / 2) - (window_height / 2)) main.geometry( f"{window_width}x{window_height}+{x_coordinate}+{y_coordinate}") main.protocol('WM_DELETE_WINDOW', main_exit_function) for n in range(4): # Loop to specify the needed column/row configures main.grid_columnconfigure(n, weight=1) for n in range(5): main.grid_rowconfigure(n, weight=1) # The entire top bar/menu is only present during standalone version ------------------------------------------- if not combined_with_ffmpeg_audio_encoder: my_menu_bar = Menu(main, tearoff=0) main.config(menu=my_menu_bar) file_menu = Menu(my_menu_bar, tearoff=0, activebackground='dim grey') my_menu_bar.add_cascade(label='File', menu=file_menu) file_menu.add_command( label='Exit', command=main_exit_function) # Exits the program options_menu = Menu(my_menu_bar, tearoff=0, activebackground='dim grey') my_menu_bar.add_cascade(label='Options', menu=options_menu) def set_ffmpeg_path(): global ffmpeg path = filedialog.askopenfilename( title='Select Location to "ffmpeg.exe"', initialdir='/', filetypes=[('ffmpeg', 'ffmpeg.exe')]) if path == '': pass elif path != '': ffmpeg = str(pathlib.Path(path)) config.set('ffmpeg_path', 'path', ffmpeg) with open(config_file, 'w') as configfile: config.write(configfile) options_menu.add_command(label='Set path to FFMPEG', command=set_ffmpeg_path) options_menu.add_separator() def reset_config(): msg = messagebox.askyesno( title='Warning', message= 'Are you sure you want to reset the config.ini file settings?' ) if not msg: pass if msg: try: config.set('ffmpeg_path', 'path', '') with open(config_file, 'w') as configfile: config.write(configfile) messagebox.showinfo( title='Prompt', message='Please restart the program') except: pass main.destroy() options_menu.add_command(label='Reset Configuration File', command=reset_config) from Packages.about import openaboutwindow def open_browser_for_ffmpeg(): import webbrowser webbrowser.open_new_tab( 'https://www.gyan.dev/ffmpeg/builds/ffmpeg-git-essentials.7z' ) help_menu = Menu(my_menu_bar, tearoff=0, activebackground="dim grey") my_menu_bar.add_cascade(label="Help", menu=help_menu) help_menu.add_command(label="Download FFMPEG", command=open_browser_for_ffmpeg) help_menu.add_separator() help_menu.add_command(label="About", command=openaboutwindow) # ------------------------------------------- The entire top bar/menu is only present during standalone version # Bundled Apps ------------------------------------------------------------------------------------------------ config_file = 'Runtime/config.ini' # Defines location of config.ini config = ConfigParser() config.read(config_file) # This creates the config file if on the standalone version --------------------------------------------------- if not combined_with_ffmpeg_audio_encoder: if not config.has_section( 'ffmpeg_path'): # Create config parameters config.add_section('ffmpeg_path') if not config.has_option('ffmpeg_path', 'path'): config.set('ffmpeg_path', 'path', '') try: with open(config_file, 'w') as configfile: config.write(configfile) except: messagebox.showinfo( title='Error', message= 'Could Not Write to config.ini file, delete and try again') # --------------------------------------------------- This creates the config file if on the standalone version # Define location of FFMPEG in a variable --------------------------------------------------------------------- ffmpeg = pathlib.Path(config['ffmpeg_path']['path'].replace('"', '')) # --------------------------------------------------------------------- Define location of FFMPEG in a variable # Code needed to add location of ffmpeg.exe in the event it's missing for standalone version ------------------ if not combined_with_ffmpeg_audio_encoder: if not pathlib.Path(ffmpeg).is_file( ): # Checks config for bundled app paths path ------------------------ def check_ffmpeg( ): # FFMPEG ------------------------------------------------------------------------- global ffmpeg import shutil def write_path_to_ffmpeg( ): # Writes path to ffmpeg to the config.ini file try: config.set('ffmpeg_path', 'path', ffmpeg) with open(config_file, 'w') as configfile: config.write(configfile) except: pass if shutil.which('ffmpeg') is not None: ffmpeg = str(pathlib.Path( shutil.which('ffmpeg'))).lower() messagebox.showinfo( title='Prompt!', message='ffmpeg.exe found on system PATH, ' 'automatically setting path to location.\n\n' 'Note: This can be changed in the config.ini file' ' or in the Options menu') if pathlib.Path("Apps/ffmpeg/ffmpeg.exe").is_file(): rem_ffmpeg = messagebox.askyesno( title='Delete Included ffmpeg?', message= 'Would you like to delete the included FFMPEG?' ) if rem_ffmpeg: try: shutil.rmtree( str(pathlib.Path("Apps/ffmpeg"))) except: pass write_path_to_ffmpeg() elif pathlib.Path("Apps/ffmpeg/ffmpeg.exe").is_file(): messagebox.showinfo( title='Info', message='Program will use the included ' '"ffmpeg.exe" located in the "Apps" folder') ffmpeg = str(pathlib.Path("Apps/ffmpeg/ffmpeg.exe")) write_path_to_ffmpeg() else: error_prompt = messagebox.askyesno( title='Error!', message='Cannot find ffmpeg, ' 'please navigate to "ffmpeg.exe"') if not error_prompt: messagebox.showerror( title='Error!', message= 'Program requires ffmpeg.exe to work correctly' ) main.destroy() if error_prompt: set_ffmpeg_path() if not pathlib.Path(ffmpeg).is_file(): messagebox.showerror( title='Error!', message= 'Program requires ffmpeg.exe to work correctly' ) main.destroy() check_ffmpeg( ) # FFMPEG ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------ Bundled Apps # ------------------ Code needed to add location of ffmpeg.exe in the event it's missing for standalone version # Link Frame -------------------------------------------------------------------------------------------------- link_frame = LabelFrame(main, text=' Paste Link ') link_frame.grid(row=0, columnspan=4, sticky=E + W, padx=20, pady=(10, 10)) link_frame.configure(fg="white", bg="#434547", bd=3) link_frame.rowconfigure(1, weight=1) link_frame.columnconfigure(0, weight=1) link_frame.columnconfigure(1, weight=1) # -------------------------------------------------------------------------------------------------- Link Frame # Options Frame ----------------------------------------------------------------------------------------------- options_frame = LabelFrame(main, text=' Options ') options_frame.grid(row=2, columnspan=4, sticky=E + W, padx=20, pady=(10, 10)) options_frame.configure(fg="white", bg="#434547", bd=3) options_frame.rowconfigure(1, weight=1) options_frame.columnconfigure(0, weight=1) options_frame.columnconfigure(1, weight=1) # ----------------------------------------------------------------------------------------------- Options Frame # Input Frame ------------------------------------------------------------------------------------------------- global link_input_label input_frame = LabelFrame(main, text=' Input ') input_frame.grid(row=1, columnspan=4, sticky=E + W, padx=20, pady=(4, 10)) input_frame.configure(fg="white", bg="#434547", bd=3) input_frame.rowconfigure(1, weight=1) input_frame.columnconfigure(0, weight=1) input_frame.columnconfigure(1, weight=1) link_input_label = Label( input_frame, text='Please Paste Link Above and Select "Add Link"', background="#434547", foreground="white", height=1, font=("Helvetica", 10)) link_input_label.grid(row=0, column=0, columnspan=4, padx=8, pady=(4, 7), sticky=W + E) # ------------------------------------------------------------------------------------------------- Input Frame # File Output ------------------------------------------------------------------------------------------------- def file_save(): global VideoOutput save_entry.config(state=NORMAL) # save_entry.delete( 0, END ) # This function clears entry box in order to add new link to entry box save_entry.config(state=DISABLED) # VideoOutput = filedialog.askdirectory( parent=main ) # Pop up window to choose a save directory location if VideoOutput: save_for_entry = '"' + VideoOutput + '/"' # Completes save directory and adds quotes save_entry.config(state=NORMAL) # save_entry.insert( 0, save_for_entry) # Adds download_link to entry box save_entry.config(state=DISABLED) # start_job_btn.config(state=NORMAL) # Enables Button # ------------------------------------------------------------------------------------------------- File Output # Best Video Function ----------------------------------------------------------------------------------------- def set_video_only(): if video_only.get( ) == 'on': # If video checkbutton is checked enable video options menu and set audio off highest_quality_audio_only.set('') video_menu_options_menu.config(state=NORMAL) audio_menu_options_menu.config(state=DISABLED) audio_menu_options.set('Extract Only') if video_only.get( ) != 'on': # If not checked, set video_only to on video_only.set( 'on' ) # This prevents you from being able to de-select the check button # ----------------------------------------------------------------------------------------- Audio Only Function def highest_quality_audio_only_toggle(): if highest_quality_audio_only.get( ) == 'on': # If audio checkbutton is checked video_only.set( '') # enables video options menu and set audio to off video_menu_options_menu.config(state=DISABLED) audio_menu_options_menu.config(state=NORMAL) if highest_quality_audio_only.get( ) != 'on': # If not checked, set audio_only to on highest_quality_audio_only.set( 'on' ) # This prevents you from being able to de-select the check button # Video Only Checkbutton -------------------------------------------------------------------------------------- video_only = StringVar() video_only_checkbox = Checkbutton( options_frame, text='Best Video + Audio\nMuxed File', variable=video_only, onvalue='on', offvalue='', command=set_video_only, takefocus=False) video_only_checkbox.grid(row=0, column=1, columnspan=1, rowspan=1, padx=10, pady=6, sticky=N + S + E + W) video_only_checkbox.configure(background="#434547", foreground="white", activebackground="#434547", activeforeground="white", selectcolor="#434547", font=("Helvetica", 12)) video_only.set('on') # Enables Best Video by default # -------------------------------------------------------------------------------------- Video Only Checkbutton # Highest Quality Audio Only ---------------------------------------------------------------------------------- highest_quality_audio_only = StringVar() highest_quality_audio_only_checkbox = Checkbutton( options_frame, text='Audio Only', variable=highest_quality_audio_only, onvalue='on', offvalue='', command=highest_quality_audio_only_toggle, takefocus=False) highest_quality_audio_only_checkbox.grid(row=0, column=2, columnspan=1, rowspan=1, padx=10, pady=3, sticky=N + S + E + W) highest_quality_audio_only_checkbox.configure( background="#434547", foreground="white", activebackground="#434547", activeforeground="white", selectcolor="#434547", font=("Helvetica", 12)) highest_quality_audio_only.set('') # Disables audio only by default # ---------------------------------------------------------------------------------- Highest Quality Audio Only # Download Rate ----------------------------------------------------------------------------------------------- def download_rate_menu_hover(e): download_rate_menu["bg"] = "grey" download_rate_menu["activebackground"] = "grey" def download_rate_menu_hover_leave(e): download_rate_menu["bg"] = "#23272A" download_rate = StringVar(main) download_rate_choices = { 'Unlimited': 131072000000000, '10 - KiB (Slowest)': 1280, '50 - KiB': 6400, '100 - KiB': 12800, '250 - KiB': 32000, '500 - KiB': 64000, '750 - KiB': 96000, '1 - MiB': 131072, '5 - MiB': 655360, '10 - MiB': 1310720, '30 - MiB': 3932160, '50 - MiB': 6553600, '100 - MiB': 13107200, '250 - MiB': 32768000, '500 - MiB': 65536000, '750 - MiB': 98304000, '1000 - MiB (Fastest)': 13107200000 } download_rate_menu_label = Label(options_frame, text="Download Rate :", background="#434547", foreground="white") download_rate_menu_label.grid(row=0, column=0, columnspan=1, padx=10, pady=(3, 10), sticky=W + E) download_rate_menu = OptionMenu(options_frame, download_rate, *download_rate_choices.keys()) download_rate_menu.config(background="#23272A", foreground="white", highlightthickness=1, width=15) download_rate_menu.grid(row=1, column=0, columnspan=1, padx=10, pady=(3, 20)) download_rate.set('Unlimited') download_rate_menu["menu"].configure(activebackground="dim grey") download_rate_menu.bind("<Enter>", download_rate_menu_hover) download_rate_menu.bind("<Leave>", download_rate_menu_hover_leave) # ----------------------------------------------------------------------------------------------- Download Rate # Video Options ----------------------------------------------------------------------------------------------- def video_menu_options_menu_hover(e): video_menu_options_menu["bg"] = "grey" video_menu_options_menu["activebackground"] = "grey" def video_menu_options_menu_hover_leave(e): video_menu_options_menu["bg"] = "#23272A" video_menu_options = StringVar(main) video_menu_options_choices = { '(bv+ba/b) Best video + audio format ' 'and combine both, or download best combined format': 'bv+ba/b', '(Same as above with video up to 480p)': 'bv*[height<=480]+ba/b[height<=480] / wv*+ba/w', '(Same as above with video up to 720p)': 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w', '(Same as above with video up to 1080p)': 'bv*[height<=1080]+ba/b[height<=1080] / wv*+ba/w', '(Same as above with video up to 1440p)': 'bv*[height<=1440]+ba/b[height<=1440] / wv*+ba/w', '(Same as above with video up to 2160p)': 'bv*[height<=2160]+ba/b[height<=2160] / wv*+ba/w', '(Default) (bv*+ba/b) Best video and if missing audio, ' 'merge it with best available audio': 'bv*+ba/b', '(bv) Best video only': 'bv', 'Download the best h264 video, ' 'or best video if no such codec': '(bv * +ba / b)[vcodec ^= avc1] / (bv * +ba / b)' } video_menu_options_menu = OptionMenu( options_frame, video_menu_options, *video_menu_options_choices.keys()) video_menu_options_menu.config(background="#23272A", foreground="white", highlightthickness=1, width=15, anchor=W) video_menu_options_menu.grid(row=1, column=1, columnspan=1, padx=10, pady=(3, 20)) video_menu_options.set( '(Default) (bv*+ba/b) Best video and if missing audio, ' 'merge it with best available audio') video_menu_options_menu["menu"].configure(activebackground="dim grey") video_menu_options_menu.bind("<Enter>", video_menu_options_menu_hover) video_menu_options_menu.bind("<Leave>", video_menu_options_menu_hover_leave) # ----------------------------------------------------------------------------------------------- Video Options # Audio Options ----------------------------------------------------------------------------------------------- def audio_menu_options_menu_hover(e): audio_menu_options_menu["bg"] = "grey" audio_menu_options_menu["activebackground"] = "grey" def audio_menu_options_menu_hover_leave(e): audio_menu_options_menu["bg"] = "#23272A" audio_menu_options = StringVar(main) audio_menu_options_choices = { 'Extract Only': '', 'Encode to mp3': 'mp3', 'Encode to flac': 'flac', 'Encode to m4a': 'm4a', 'Encode to opus': 'opus', 'Encode to vorbis': 'vorbis', 'Encode to wav': 'wav' } audio_menu_options_menu = OptionMenu( options_frame, audio_menu_options, *audio_menu_options_choices.keys()) audio_menu_options_menu.config(background="#23272A", foreground="white", highlightthickness=1, width=15, anchor=W, state=DISABLED) audio_menu_options_menu.grid(row=1, column=2, columnspan=1, padx=10, pady=(3, 20)) audio_menu_options.set('Extract Only') audio_menu_options_menu["menu"].configure(activebackground="dim grey") audio_menu_options_menu.bind("<Enter>", audio_menu_options_menu_hover) audio_menu_options_menu.bind("<Leave>", audio_menu_options_menu_hover_leave) # ----------------------------------------------------------------------------------------------- Audio Options # Add Link to variable ---------------------------------------------------------------------------------------- def apply_link(): global download_link, link_input_label, extracted_title_name link_entry.config(state=NORMAL) # link_entry.delete( 0, END ) # This function clears entry box in order to add new link to entry box link_entry.config(state=DISABLED) # download_link = text_area.get(1.0, END).rstrip( "\n") # Pasted download link and strips the unneeded newline text_area.delete( 1.0, END ) # Deletes entry box where you pasted your link as it stores it into var link_entry.config(state=NORMAL) # link_entry.insert(0, download_link) # Adds download_link to entry box link_entry.config(state=DISABLED) # save_btn.config(state=NORMAL) # try: # The code below checks link input for the title and adds it to a variable for use with the gui with yt_dlp.YoutubeDL({'noplaylist': True}) as ydl: dl_link_input = ydl.extract_info(download_link, download=False) string_one = sub('[^a-zA-Z0-9 \n]', '', dl_link_input['title']) string_two = " ".join(string_one.split()) extracted_title_name = pathlib.Path( string_two[:128]).with_suffix('') except: extracted_title_name = download_link link_input_label.configure(text=extracted_title_name) # ---------------------------------------------------------------------------------------------------- Add Link # Start Job --------------------------------------------------------------------------------------------------- def start_job( ): # This is the progress window and everything that has to do with actually processing the file global download_link def close_encode(): confirm_exit = messagebox.askyesno( title='Prompt', message="Are you sure you want to stop progress?", parent=window) if confirm_exit: # If user selects 'Yes' to the above message prompt, destroy the window in question window.destroy() def close_window( ): # This thread is needed in order to close the window while the GUI is processing a file thread = threading.Thread(target=close_encode) thread.start() window = Toplevel(main) # Programs download window window.title( extracted_title_name ) # Takes extracted_title_name and adds it as the windows title window.configure(background='#434547') encode_label = Label(window, text='- ' * 22 + 'Progress ' + '- ' * 22, font=('Times New Roman', 14), background='#434547', foreground='white') encode_label.grid(column=0, columnspan=2, row=0) window.grid_columnconfigure(0, weight=1) window.grid_rowconfigure(0, weight=1) window.grid_rowconfigure(1, weight=1) window.protocol('WM_DELETE_WINDOW', close_window) window.geometry('600x140') encode_window_progress = Text(window, height=2, relief=SUNKEN, bd=3) encode_window_progress.grid(row=1, column=0, columnspan=2, pady=(10, 6), padx=10, sticky=E + W) encode_window_progress.insert(END, '') app_progress_bar = ttk.Progressbar(window, orient=HORIZONTAL, mode='determinate') app_progress_bar.grid(row=2, columnspan=2, pady=(10, 10), padx=15, sticky=E + W) def my_hook( d ): # This updates the progress bar with the correct percentage if d['status'] == 'downloading': p = d['_percent_str'] p = p.replace('%', '') app_progress_bar['value'] = float(p) class MyLogger: # ytb-dl logger, allows the program to get all the needed info from the program global download_info_string def debug(self, msg): # For compatability with youtube-dl, both debug and info are passed into debug # You can distinguish them by the prefix '[debug] ' if msg.startswith('[debug] '): pass else: self.info(msg) def info(self, msg): encode_window_progress.delete('1.0', END) encode_window_progress.insert(END, msg) def warning(self, msg): pass def error(self, msg): pass if video_only.get( ) == 'on': # If "Best Video..." is selected then use these options for ytb-dl ydl_opts = { 'ratelimit': download_rate_choices[download_rate.get()], 'progress_hooks': [my_hook], 'noplaylist': True, 'overwrites': True, 'merge_output_format': 'mkv', 'final_ext': 'mkv', 'outtmpl': str(pathlib.Path(VideoOutput)) + '/%(title)s.%(ext)s', 'ffmpeg_location': str(pathlib.Path(ffmpeg)), 'logger': MyLogger(), "progress_with_newline": True, 'format': video_menu_options_choices[video_menu_options.get()], 'prefer_ffmpeg': True } if video_only.get() != 'on' and audio_menu_options.get( ) == 'Extract Only': # If "Best Video..." is NOT selected and "Audio Menu" is set to Extract Only ydl_opts = { 'ratelimit': download_rate_choices[download_rate.get()], 'progress_hooks': [my_hook], 'noplaylist': True, 'overwrites': True, 'outtmpl': str(pathlib.Path(VideoOutput)) + '/%(title)s.%(ext)s', 'ffmpeg_location': str(pathlib.Path(ffmpeg)), 'logger': MyLogger(), "progress_with_newline": True, 'format': 'bestaudio/best', 'extractaudio': True, 'prefer_ffmpeg': True } if video_only.get() != 'on' and audio_menu_options.get( ) != 'Extract Only': # If "Best Video..." is NOT selected and "Audio Menu" is set to encode to another codec ydl_opts = { 'ratelimit': download_rate_choices[download_rate.get()], 'progress_hooks': [my_hook], 'noplaylist': True, 'overwrites': True, 'outtmpl': str(pathlib.Path(VideoOutput)) + '/%(title)s.%(ext)s', 'ffmpeg_location': str(pathlib.Path(ffmpeg)), 'logger': MyLogger(), "progress_with_newline": True, 'format': 'bestaudio/best', 'extractaudio': True, 'prefer_ffmpeg': True, 'postprocessors': [{ 'key': 'FFmpegExtractAudio', 'preferredcodec': audio_menu_options_choices[audio_menu_options.get()], 'preferredquality': '0' }] } with yt_dlp.YoutubeDL( ydl_opts ) as ydl: # Block of code needed to process the link/file ydl.download([download_link]) window.destroy( ) # Once the job is complete this destroys the download/processing window # --------------------------------------------------------------------------------------------------- Start Job # Buttons and Entry Box's ------------------------------------------------------------------------------------- text_area = scrolledtext.ScrolledText(link_frame, wrap=WORD, width=69, height=1, font=("Times New Roman", 14), foreground="grey") text_area.insert(END, "Right Click or 'Ctrl + V'") text_area.grid(row=0, column=0, columnspan=3, pady=(1, 5), padx=10, sticky=W + E) # ------------------------------------------------------------------ Right click menu to paste in text_area box def paste_clipboard( ): # Allows user to paste what ever is in their clipboard with right click and paste text_area.delete(1.0, END) text_area.config(foreground="black") text_area.insert(END, pyperclip.paste()) def remove_text( e): # Deletes current text in text box upon 'Left Clicking' text_area.config(foreground="black") text_area.delete(1.0, END) link_input_label.configure( text='Please Paste Link Above and Select "Add Link"') link_entry.config(state=NORMAL) # link_entry.delete( 0, END ) # This function clears entry box in order to add new link to entry box link_entry.config(state=DISABLED) # m = Menu(main, tearoff=0) # Pop up menu for 'Paste' m.add_command(label="Paste", command=paste_clipboard) def do_popup( event ): # This code allows the program to know where the cursor is upon right clicking try: m.tk_popup(event.x_root, event.y_root) finally: m.grab_release() text_area.bind("<Button-3>", do_popup) # Uses right click to make a function text_area.bind("<Button-1>", remove_text) # Uses left click to make a function # Right click menu to paste in text_area box ------------------------------------------------------------------ link_entry = Entry(link_frame, borderwidth=4, background="#CACACA", state=DISABLED, width=70) link_entry.grid(row=1, column=1, columnspan=2, padx=10, pady=(0, 0), sticky=W + E) def apply_btn_hover(e): apply_btn["bg"] = "grey" def apply_btn_hover_leave(e): apply_btn["bg"] = "#8b0000" apply_btn = Button(link_frame, text="Add Link", command=apply_link, foreground="white", background="#8b0000", width=30) apply_btn.grid(row=1, column=0, columnspan=1, padx=10, pady=5, sticky=W) apply_btn.bind("<Enter>", apply_btn_hover) apply_btn.bind("<Leave>", apply_btn_hover_leave) def save_btn_hover(e): save_btn["bg"] = "grey" def save_btn_hover_leave(e): save_btn["bg"] = "#8b0000" save_btn = Button(main, text="Save Directory", command=file_save, foreground="white", background="#8b0000", state=DISABLED) save_btn.grid(row=4, column=0, columnspan=1, padx=10, pady=(15, 0), sticky=W + E) save_btn.bind("<Enter>", save_btn_hover) save_btn.bind("<Leave>", save_btn_hover_leave) save_entry = Entry(main, borderwidth=4, background="#CACACA", state=DISABLED) save_entry.grid(row=4, column=1, columnspan=3, padx=10, pady=(15, 0), sticky=W + E) def start_job_btn_hover(e): start_job_btn["bg"] = "grey" def start_job_btn_hover_leave(e): start_job_btn["bg"] = "#8b0000" start_job_btn = Button( main, text="Start Job", command=lambda: threading.Thread(target=start_job).start(), foreground="white", background="#8b0000", state=DISABLED) start_job_btn.grid(row=5, column=3, columnspan=1, padx=10, pady=(15, 15), sticky=N + S + W + E) start_job_btn.bind("<Enter>", start_job_btn_hover) start_job_btn.bind("<Leave>", start_job_btn_hover_leave) # ------------------------------------------------------------------------------------- Buttons and Entry Box's # End Loop ---------------------------------------------------------------------------------------------------- main.mainloop()