class MoveControl(LabelFrame): def __init__(self, root, prtr, settings, log, *arg): fn = os.path.join(settings.cmdFolder, "images", "control_xyz.png") self.image = Image.open(fn) self.photo = ImageTk.PhotoImage(self.image) LabelFrame.__init__(self, root, *arg, text="Movement") self.app = root self.hilite = None self.hilitemask = None self.settings = settings self.printer = prtr self.log = log l = Label(self, text="mm/min") l.grid(row=1, column=2) l = Label(self, text="X/Y Feed Rate:") l.grid(row=2, column=1, sticky=E) self.xyfeed = Spinbox(self, width=10, justify=RIGHT, from_=0, to=MAXFEED) self.xyfeed.grid(row=2, column=2) self.xyfeed.delete(0, END) self.xyfeed.insert(0, settings.xyfeed) self.xyfeed.bind("<FocusOut>", self.valxyFeed) self.xyfeed.bind("<Leave>", self.valxyFeed) l = Label(self, text="Z Feed Rate:") l.grid(row=3, column=1, sticky=E) self.zfeed = Spinbox(self, width=10, justify=RIGHT, from_=0, to=MAXFEED) self.zfeed.grid(row=3, column=2) self.zfeed.delete(0, END) self.zfeed.insert(0, settings.zfeed) self.zfeed.bind("<FocusOut>", self.valzFeed) self.zfeed.bind("<Leave>", self.valzFeed) self.canvas = Canvas(self, width=self.image.size[0], height=self.image.size[1], *arg) self.canvas.create_image((0, 0), image=self.photo, anchor=N+W) self.canvas.grid(row=4, column=1, columnspan=2) for m in imageMasks: self.canvas.create_oval((m[0][0]-mask_rad, m[0][1]-mask_rad, m[0][0]+mask_rad, m[0][1]+mask_rad), outline="#FF0000", width=4, tags=m[1], state=HIDDEN) self.canvas.bind("<Button-1>", self.OnLeftDown) self.canvas.bind("<Motion>", self.OnMotion) self.canvas.bind("<Enter>", self.OnEnter) self.canvas.bind("<Leave>", self.OnLeave) self.bAllOff = Button(self, text="Release Motors", command=self.allMotorsOff) self.bAllOff.grid(row=5, column=1, columnspan=2) def valxyFeed(self, *arg): x = self.validFeed(self.xyfeed.get(), 'XY') if x == None: self.xyfeed.delete(0, END) self.xyfeed.insert(0, "%d" % self.settings.xyfeed) return True if self.settings.xyfeed != x: self.settings.xyfeed = x self.settings.setModified() return True def valzFeed(self, *arg): x = self.validFeed(self.zfeed.get(), 'Z') if x == None: self.zfeed.delete(0, END) self.zfeed.insert(0, "%d" % self.settings.zfeed) return True if self.settings.zfeed != x: self.settings.zfeed = x self.settings.setModified() return True def validFeed(self, fv, axis): try: x = int(fv) except: self.log.logMsg("Value for %s feed rate not a valid integer" % axis) return None if x <=0 or x >MAXFEED: self.log.logMsg("Value for %s feed rate out of range(0-5000)" % axis) return None return x def allMotorsOff(self): if self.app.printerAvailable(cmd="M84"): self.printer.send_now("M84") def OnMotion(self, e): for i in range(len(imageGeometry)): if boundBy((e.x, e.y), imageGeometry[i][0]): self.setHilite(i) return if self.hilite != None: self.clearHilite() def OnEnter(self, e): self.clearHilite() def OnLeave(self, e): self.clearHilite() def setHilite(self, i): if i != self.hilite: self.canvas.delete("HILITE") self.canvas.create_rectangle(imageGeometry[i][0], outline="#C85E5D", width=3, fill="gray", stipple="gray50", tags="HILITE") self.hilite = i if self.hilitemask: self.canvas.itemconfig(self.hilitemask, state=HIDDEN) if imageGeometry[i][2]: self.hilitemask = imageGeometry[i][2] self.canvas.itemconfig(self.hilitemask, state=NORMAL) def clearHilite(self): self.canvas.delete("HILITE") self.hilite = None self.hilitemask = None for m in imageMasks: self.canvas.itemconfig(m[1], state=HIDDEN) def OnLeftDown(self, e): if self.app.printerAvailable(cmd="G1"): for g in imageGeometry: if boundBy((e.x, e.y), g[0]): if "G1" in g[1]: if "X" in g[1]: feed = self.settings.xyfeed elif "Y" in g[1]: feed = self.settings.xyfeed elif "Z" in g[1]: feed = self.settings.zfeed else: feed = 100 self.printer.send_now("G91") self.printer.send_now(g[1] + " F" + str(feed)) self.printer.send_now("G90") else: self.printer.send_now(g[1]) break
class Extruder(LabelFrame): def __init__(self, root, prtr, settings, log, *arg): LabelFrame.__init__(self, root, *arg, text="Extruder") self.app = root self.printer = prtr self.settings = settings self.log = log self.bExtrude = Button(self, text="Extrude", width=10, command=self.doExtrude) self.bExtrude.grid(row=1, column=1, padx=2) self.spDistance = Spinbox(self, from_=1, to=MAXDIST, width=6, justify=RIGHT) self.spDistance.grid(row=1, column=2) self.spDistance.delete(0, END) self.spDistance.insert(0, STARTDIST) self.spDistance.bind("<FocusOut>", self.valDistance) self.spDistance.bind("<Leave>", self.valDistance) l = Label(self, text="mm", justify=LEFT) l.grid(row=1, column=3, sticky=W) self.bReverse = Button(self, text="Reverse", width=10, command=self.doReverse) self.bReverse.grid(row=2, column=1, padx=2) self.spSpeed = Spinbox(self, from_=1, to=MAXFEED, width=6, justify=RIGHT) self.spSpeed.grid(row=2, column=2) self.spSpeed.delete(0, END) self.spSpeed.insert(0, self.settings.efeed) self.spSpeed.bind("<FocusOut>", self.valSpeed) self.spSpeed.bind("<Leave>", self.valSpeed) l = Label(self, text="mm/min", justify=LEFT) l.grid(row=2, column=3, sticky=W) def valDistance(self, *arg): invalid = False try: y = float(self.spDistance.get()) except: self.log.logMsg("Value for distance not a valid number") invalid = True else: if y <=0 or y >MAXDIST: self.log.logMsg("Value for Distance out of range (0-%d)" % MAXDIST) invalid = True if invalid: self.spDistance.delete(0, END) self.spDistance.insert(0, STARTDIST) return True def valSpeed(self, *arg): invalid = False try: x = int(self.spSpeed.get()) except: self.log.logMsg("Value for E feed rate not a valid integer") invalid = True else: if x <=0 or x >MAXFEED: self.log.logMsg("Value for E feed rate out of range(0-%d)" % MAXFEED) invalid = True if invalid: self.spSpeed.delete(0, END) self.spSpeed.insert(0, "%d" % self.settings.efeed) else: if self.settings.efeed != x: self.settings.efeed = x self.settings.setModified() return True def doExtrude(self): if self.app.printerAvailable(cmd="G91"): dist = self.spDistance.get() self.printer.send_now("G91") self.printer.send_now("G1 E%s F%s" % (dist, self.settings.efeed)) self.printer.send_now("G90") def doReverse(self): if self.app.printerAvailable(cmd="G91"): dist = self.spDistance.get() self.printer.send_now("G91") self.printer.send_now("G1 E-%s F%s" % (dist, self.settings.efeed)) self.printer.send_now("G90")
class PVapplicaton(Frame): """ classdocs """ def __init__(self, master=None): """ Constructor """ Frame.__init__(self, master, name='pvApplication', bg='black', padx=5, pady=5) # set black background, pad sides with 15 points, top/bottom 5 points # fill=BOTH fills in padding with background color # w/o fill=BOTH padding is default color # side=TOP is the default self.pack(fill=BOTH) master.resizable(False, False) # not resizable in x or y master.title(PVAPP_TXT) # set title bar of master (a.k.a. root) master.protocol("WM_DELETE_WINDOW", self._quit) # close window to quit self.validationConstants = self.readJSON('validationConstants') self.messagetext = self.readJSON('messagetext' + '.' + LANGUAGE) MAX_STRINGS = self.validationConstants["pvapplication"]["numStrs"] MAX_MODULES = self.validationConstants["pvapplication"]["numMods"] MAX_SUNS = self.validationConstants["pvapplication"]["sysEe"] CAPTION_FONT = nametofont('TkCaptionFont') # font for titles # PVsystem pvSys = self.pvSys = PVsystem() # variables numStrs = self.numStrs = IntVar(self, NUMBERSTRS, 'numStrs') numMods = self.numMods = IntVar(self, NUMBERMODS, 'numMods') numCells = self.numCells = IntVar(self, NUMBERCELLS, 'numCells') txtIsys = self.txtIsys = DoubleVar(self, name='txtIsys') txtVsys = self.txtVsys = DoubleVar(self, name='txtVsys') txtPsys = self.txtPsys = DoubleVar(self, name='txtPsys') txtImp = self.txtImp = StringVar(self, name='txtImp') txtVmp = self.txtVmp = StringVar(self, name='txtVmp') txtPmp = self.txtPmp = StringVar(self, name='txtPmp') txtIsc = self.txtIsc = StringVar(self, name='txtIsc') txtVoc = self.txtVoc = StringVar(self, name='txtVoc') txtFF = self.txtFF = StringVar(self, name='txtFF') txtEff = self.txtEff = StringVar(self, name='txtEff') sysEe = self.sysEe = DoubleVar(self, 1, name='sysEe') txtImp.set("{:7.3f}".format(self.pvSys.Imp)) # [A] txtVmp.set("{:7.3f}".format(self.pvSys.Vmp)) # [V] txtPmp.set("{:7.3f}".format(self.pvSys.Pmp / 1000)) # [kW] txtIsc.set("{:7.3f}".format(self.pvSys.Isc)) # [A] txtVoc.set("{:7.3f}".format(self.pvSys.Voc)) # [V] txtFF.set("{:7.3f}".format(self.pvSys.FF * 100)) # [%] txtEff.set("{:7.3f}".format(self.pvSys.eff * 100)) # [%] self.msgtext = StringVar(self, READY_MSG, 'msgtext') # must register vcmd and invcmd as Tcl functions vcmd = (self.register(self.validateWidget), '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W') invcmd = (self.register(self.invalidWidget), '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W') # SP logo # convert image to tk-compatible format (.gif, .pgm, or .ppm) self.SPlogo = ImageTk.PhotoImage(Image.open(SPLOGO)) # bg='black' fills extra space with black # anchor=W aligns photoimage on left side, NW is no different # padding is ignored by images, use borderwidth Label(self, image=self.SPlogo, borderwidth=5, bg='black', anchor=W).pack(fill=BOTH) # fill=BOTH expands the photoimage to fill parent frame # w/o fill=BOTH photoimage is centered in frame even with anchor=W # Intro text introText = 'PVmismatch calculates I-V and P-V curves as well as the' introText += ' max power point (MPP) for any sized system.\nSet the' introText += ' number of strings in the system, the number of modules' introText += ' per string and the number cells per module.' # anchor=W aligns message on left side, NW is no different # fg='white' sets text color to white, default is black, so it doesn't # show on black background # default aspect is 150%, about as wide as high, or set width>0 Message(self, text=introText, width=750, bg='black', fg='white', anchor=W).pack(fill=BOTH) # fill=BOTH expands the message to fill parent frame # w/o fill=BOTH message is centered in frame even with anchor=W # PVsystem frame pvSysFrame = self.pvSysFrame = Frame(master, name='pvSysFrame') # fill=BOTH keeps widgets in frame on left when window is resized pvSysFrame.pack(fill=BOTH) # PVsystem matplotlib figure canvas self.pvSysPlotFrame = Frame(pvSysFrame, name='pvSysPlotFrame') pvSysPlotFrame = self.pvSysPlotFrame pvSysPlotFrame.pack(side=RIGHT) pvSysPlot = self.pvSysPlot = pvSys.plotSys() self.pvSysFigCanvas = FigureCanvasTkAgg(pvSysPlot, master=pvSysPlotFrame, resize_callback=None) pvSysFigCanvas = self.pvSysFigCanvas pvSysFigCanvas.get_tk_widget()._name = 'pvSysFigCanvas' # IGNORE:W0212 pvSysFigCanvas.show() # NB: FigureCanvasTkAgg._tkcanvas is FigureCanvasTkAgg.get_tk_widget() pvSysFigCanvas.get_tk_widget().pack(fill=BOTH) pvSysToolbar = NavigationToolbar2TkAgg(pvSysFigCanvas, pvSysPlotFrame) pvSysToolbar.update() pvSysToolbar.pack(fill=BOTH) # PVsystem data frame pvSysDataFrame = self.pvSysDataFrame = Frame(pvSysFrame, name='pvSysDataFrame') pvSysDataFrame.pack(side=LEFT) _row = 0 Label(pvSysDataFrame, text='PVsystem', font=CAPTION_FONT).grid(row=_row, columnspan=3, sticky=W) # number of strings _row += 1 # row 1 Label(pvSysDataFrame, text='Number of Strings').grid(row=_row, columnspan=2, sticky=W) # use textVar to set number of strings from LOAD, RESET or default spinboxCnf = { 'name': 'numStrSpinbox', 'from_': 1, 'to': MAX_STRINGS, 'textvariable': numStrs, 'width': 5, 'validate': 'all', 'validatecommand': vcmd, 'invalidcommand': invcmd, 'command': self.updatePVsys } self.numStrSpinbox = Spinbox(pvSysDataFrame, cnf=spinboxCnf) self.numStrSpinbox.bind("<Return>", self.keyBinding) self.numStrSpinbox.grid(row=_row, column=2) # number of modules _row += 1 # row 2 Label(pvSysDataFrame, text='Number of Modules').grid(row=_row, columnspan=2, sticky=W) # number of modules spinbox spinboxCnf = { 'name': 'numModSpinbox', 'from_': 1, 'to': MAX_MODULES, 'textvariable': numMods, 'width': 5, 'validate': 'all', 'validatecommand': vcmd, 'invalidcommand': invcmd, 'command': self.updatePVsys } self.numModSpinbox = Spinbox(pvSysDataFrame, cnf=spinboxCnf) self.numModSpinbox.bind("<Return>", self.keyBinding) self.numModSpinbox.grid(row=_row, column=2) # number of cells _row += 1 # row 3 Label(pvSysDataFrame, text='Number of Cells').grid(row=_row, columnspan=2, sticky=W) # http://www.logilab.org/card/pylintfeatures#basic-checker # pylint: disable = W0142 self.numCellOption = OptionMenu(pvSysDataFrame, numCells, *MODSIZES, command=self.updatePVsys) # pylint: enable = W0142 self.numCellOption._name = 'numCellOption' # IGNORE:W0212 self.numCellOption.grid(row=_row, column=2) # Advanced Configuration button _row += 1 # row 14 buttonCnf = { 'name': 'advCnfButton', 'text': 'Advanced Configuration', 'command': self.startAdvCnf_tk } pvStrButton = self.pvStrButton = Button(pvSysDataFrame, buttonCnf) pvStrButton.grid(row=_row, columnspan=3, sticky=(E + W)) # slider to explore IV curves _row += 1 # row 4, 5 & 6 self.pvSysScale = Scale(pvSysDataFrame, orient=HORIZONTAL, label='I-V Curve', font=CAPTION_FONT, command=self.getIV, showvalue=False, from_=0, to=(pvSys.pvconst.npts - 1)) self.pvSysScale.grid(row=_row, columnspan=3, sticky=(E + W)) # Isys Label(pvSysDataFrame, text='Isys [A]').grid(row=(_row + 1)) self.pvIsys = Entry(pvSysDataFrame, textvariable=txtIsys, width=7) self.pvIsys.grid(row=(_row + 2)) # Vsys Label(pvSysDataFrame, text='Vsys [V]').grid(row=(_row + 1), column=1) self.pvVsys = Entry(pvSysDataFrame, textvariable=txtVsys, width=7) self.pvVsys.grid(row=(_row + 2), column=1) # Psys Label(pvSysDataFrame, text='Psys [kW]').grid(row=(_row + 1), column=2) self.pvPsys = Entry(pvSysDataFrame, textvariable=txtPsys, width=7) self.pvPsys.grid(row=(_row + 2), column=2) # Imp, Vmp & Pmp _row += 3 # row 7, 8, 9, 10, 11 & 12 Label(pvSysDataFrame, text='I-V Characteristics', font=CAPTION_FONT).grid(row=_row, columnspan=3, sticky=W) Label(pvSysDataFrame, text='Imp [A]').grid(row=(_row + 1)) Label(pvSysDataFrame, text='Vmp [V]').grid(row=(_row + 1), column=1) Label(pvSysDataFrame, text='Pmp [kW]').grid(row=(_row + 1), column=2) self.pvImp = Entry(pvSysDataFrame, textvariable=txtImp, width=7, state='readonly') self.pvImp.grid(row=(_row + 2)) self.pvVmp = Entry(pvSysDataFrame, textvariable=txtVmp, width=7, state='readonly') self.pvVmp.grid(row=(_row + 2), column=1) self.pvPmp = Entry(pvSysDataFrame, textvariable=txtPmp, width=7, state='readonly') self.pvPmp.grid(row=(_row + 2), column=2) # Isc, Voc & FF Label(pvSysDataFrame, text='Isc [A]').grid(row=(_row + 3)) Label(pvSysDataFrame, text='Voc [V]').grid(row=(_row + 3), column=1) Label(pvSysDataFrame, text='FF [%]').grid(row=(_row + 3), column=2) self.pvIsc = Entry(pvSysDataFrame, textvariable=txtIsc, width=7, state='readonly') self.pvIsc.grid(row=(_row + 4)) self.pvVoc = Entry(pvSysDataFrame, textvariable=txtVoc, width=7, state='readonly') self.pvVoc.grid(row=(_row + 4), column=1) self.pvFF = Entry(pvSysDataFrame, textvariable=txtFF, width=7, state='readonly') self.pvFF.grid(row=(_row + 4), column=2) Label(pvSysDataFrame, text='Efficiency [%]').grid(row=(_row + 5), columnspan=2) self.pvEff = Entry(pvSysDataFrame, textvariable=txtEff, width=7, state='readonly') self.pvEff.grid(row=(_row + 5), column=2) # set suns _row += 6 # row 13 Label(pvSysDataFrame, text='Irradiance [suns]', font=CAPTION_FONT).grid(row=_row, columnspan=2, sticky=W) # number of modules spinbox spinboxCnf = { 'name': 'sunSpinbox', 'from_': 0.2, 'to': MAX_SUNS, 'increment': 0.1, 'textvariable': sysEe, 'width': 5, 'validate': 'all', 'validatecommand': vcmd, 'invalidcommand': invcmd, 'command': self.updatePVsys } self.sunSpinbox = Spinbox(pvSysDataFrame, cnf=spinboxCnf) self.sunSpinbox.bind("<Return>", self.keyBinding) self.sunSpinbox.grid(row=_row, column=2) # PVstring button _row += 1 # row 14 buttonCnf = { 'name': 'pvStrButton', 'text': 'PVstring', 'command': self.startPVstring_tk } pvStrButton = self.pvStrButton = Button(pvSysDataFrame, buttonCnf) pvStrButton.grid(row=_row, columnspan=3, sticky=(E + W)) # toolbar toolbar = self.toolbarframe = Frame(master, name='toolbar') toolbar.pack(fill=BOTH) self.QUIT = Button(toolbar, text='Quit', command=self._quit) self.QUIT.pack(side=RIGHT) self.SAVE = Button(toolbar, text='Save', command=self._save) self.SAVE.pack(side=RIGHT) self.LOAD = Button(toolbar, text='Load', command=self._load) self.LOAD.pack(side=RIGHT) self.RESET = Button(toolbar, text='Reset', command=self._reset) self.RESET.pack(side=RIGHT) self.UPDATE = Button(toolbar, text='Update', command=self._update) self.UPDATE.pack(side=RIGHT) self.HELP = Button(toolbar, text='Help', command=self._help) self.HELP.pack(side=RIGHT) self.MESSAGE = Message(toolbar, textvariable=self.msgtext, width=500, fg='red') self.MESSAGE.pack(side=LEFT) # Validation substitutions # %d Type of action: 1 for insert, 0 for delete, or -1 for focus, forced or # textvariable validation. # %i Index of char string to be inserted/deleted, if any, otherwise -1. # %P The value of the spinbox should edition occur. If you are configuring # the spinbox widget to have a new textvariable, this will be the value # of that textvariable. # %s The current value of spinbox before edition. # %S The text string being inserted/deleted, if any. Otherwise it is an # empty string. # %v The type of validation currently set. # %V The type of validation that triggered the callback (key, focusin, # focusout, forced). # %W The name of the spinbox widget. # TODO: Fix these functions so that delete and overwrite work def validateWidget(self, *args): # W = Tkinter.W = 'w' is already used, so use W_ instead (d, i, P, s, S, v, V, W_) = args # @UnusedVariable # IGNORE:W0612 logging.debug( "OnValidate: d={}, i={}, P={}, s={}, S={}, v={}, V={}, W={}". format(*args)) if W_ == ".pvSysFrame.pvSysDataFrame.numStrSpinbox": valType = INTEGERS valTest = lambda val: int(val) # IGNORE:W0108 elif W_ == ".pvSysFrame.pvSysDataFrame.numModSpinbox": valType = INTEGERS valTest = lambda val: int(val) # IGNORE:W0108 elif W_ == ".pvSysFrame.pvSysDataFrame.sunSpinbox": valType = FLOATS valTest = lambda val: float(val) # IGNORE:W0108 else: return False w = self.nametowidget(W_) w.config(validate=v) if S in valType: try: valTest(P) except ValueError: return False return True else: return False def invalidWidget(self, *args): (d, i, P, s, S, v, V, W_) = args # @UnusedVariable # IGNORE:W0612 logging.debug( "OnInvalid: d={}, i={}, P={}, s={}, S={}, v={}, V={}, W={}".format( *args)) if W_ == ".pvSysFrame.pvSysDataFrame.numStrSpinbox": errText = 'Invalid number of strings!' elif W_ == ".pvSysFrame.pvSysDataFrame.numModSpinbox": errText = 'Invalid number of modules!' elif W_ == ".pvSysFrame.pvSysDataFrame.sunSpinbox": errText = 'Invalid irradiance!' else: errText = 'Unknown widget!' w = self.nametowidget(W_) w.config(validate=v) self.msgtext.set(errText) self.bell() def getIV(self, *args): logging.debug('args:\n\t%r', args) x = np.float64(float(args[0]) / self.pvSys.pvconst.npts / 2.) xp = np.concatenate( (self.pvSys.pvconst.negpts, self.pvSys.pvconst.pts), axis=0).flatten() Vsys = np.interp(x, xp, self.pvSys.Vsys) Isys = np.interp(x, xp, self.pvSys.Isys) Psys = Vsys * Isys / 1000 self.txtVsys.set("{:7.3f}".format(Vsys)) self.txtIsys.set("{:7.3f}".format(Isys)) self.txtPsys.set("{:7.3f}".format(Psys)) def startPVstring_tk(self): top = Toplevel() app = PVstring_tk(self, top) app.mainloop() # please destroy me or I'll continue to run in background top.destroy() def startAdvCnf_tk(self): """ open advnaced config window """ top = Toplevel(name='advCnfTop') app = AdvCnf_tk(self, top) app.mainloop() # please destroy me or I'll continue to run in background top.destroy() def keyBinding(self, event): logging.debug('event widget:\n\t%r', event.widget) logging.debug('event widget get:\n\t%r', event.widget.get()) self.updatePVsys() def updatePVsys(self, *args, **kwargs): logging.debug('args:\n\t%r', args) logging.debug('kwargs:\n\t%r', kwargs) if args and isinstance(args[0], PVsystem_cls): pvsys = args[0] for n, pvstr in enumerate(pvsys.pvstrs): for pvmod in pvstr.pvmods: pvmod.calcMod() pvstr.calcString() logging.debug('updating pvstring #%d: Pmp = %g[W]', n, pvstr.Pstring.max()) return PVAPP = "pvapplication" try: numStrs = self.numStrs.get() if not (0 < numStrs <= self.validationConstants[PVAPP]["numStrs"]): raise PVValidationError('numStrs', numStrs) numMods = self.numMods.get() if not (0 < numMods <= self.validationConstants[PVAPP]["numMods"]): raise PVValidationError('numMods', numMods) sysEe = self.sysEe.get() if not (0 < sysEe <= self.validationConstants[PVAPP]["sysEe"]): raise PVValidationError('sysEe', sysEe) except PVValidationError as err: logging.debug('err:\n\t%r', err) errtext = self.messagetext[PVAPP][err.argname] self.msgtext.set(errtext) self.bell() return numCells = self.numCells.get() self.msgtext.set(self.messagetext[PVAPP]["Ready"]) pvconst = self.pvSys.pvconst pvcell = PVcell(Ee=sysEe) if numCells == 24: numCells = STD24 elif numCells == 72: numCells = STD72 elif numCells == 96: numCells = STD96 elif numCells == 128: numCells = STD128 pvmods = PVmodule(cell_pos=numCells, pvcells=pvcell) self.pvSys = PVsystem(pvconst, numStrs, numberMods=numMods, pvmods=pvmods) self.updateIVstats() def updateIVstats(self): # reuse sysPlot figure and update pvSysFigCanvas self.pvSysPlot = self.pvSys.plotSys(self.pvSysPlot) self.pvSysFigCanvas.show() self.txtImp.set("{:7.3f}".format(self.pvSys.Imp)) # [A] self.txtVmp.set("{:7.3f}".format(self.pvSys.Vmp)) # [V] self.txtPmp.set("{:7.3f}".format(self.pvSys.Pmp / 1000)) # [kW] self.txtIsc.set("{:7.3f}".format(self.pvSys.Isc)) # [A] self.txtVoc.set("{:7.3f}".format(self.pvSys.Voc)) # [V] self.txtFF.set("{:7.3f}".format(self.pvSys.FF * 100)) # [%] self.txtEff.set("{:7.3f}".format(self.pvSys.eff * 100)) # [%] def _help(self): logging.debug('show docs in browser') webbrowser.open(DOCS) def _update(self): self.msgtext.set(READY_MSG) self.updatePVsys() def _reset(self): # number of strings integer variable self.numStrs.set(NUMBERSTRS) # default # number of modules integer variable self.numMods.set(NUMBERMODS) # default # number of cells integer variable self.numCells.set(NUMBERCELLS) # default value is 96 self.msgtext.set(READY_MSG) # TODO: need to reset advCnf too logging.debug('reset') def _load(self): logging.debug('load *.pv file') def _save(self): logging.debug('save *.pv file') def _quit(self): # this is necessary on Windows to prevent # Fatal Python Error: PyEval_RestoreThread: NULL tstate self.master.quit() # stops mainloop self.master.destroy() def readJSON(self, JSONfilename): if not JSONfilename.endswith('json'): JSONfilename += '.json' JSONfullpath = os.path.join(JSONDIR, JSONfilename) with open(JSONfullpath, 'r') as JSONfile: JSONObjects = json.load(JSONfile) logging.debug('JSON objects loaded from %s.', JSONfullpath) return JSONObjects
class AntroidGUI(Tk): def __init__(self): Tk.__init__(self) self.protocol("WM_DELETE_WINDOW", self.myquit) self.etat = True self.readstate = True self.title("Antroid Map") self.turns = {} self.selectTurn = -1 self.caselength = 10 self.CaseMarge = 20 self.var = StringVar() self.initGUI() def initGUI(self): frame = Frame(self, width=630, height=500) self.panel = PanedWindow(frame, orient=HORIZONTAL) self.LeftFrame(self.panel) self.RightFrame(self.panel) self.panel.add(self.LFrame) self.panel.add(self.RFrame) self.panel.pack() frame.pack() def LeftFrame(self, parent): self.LFrame = Frame(parent, width=500, height=500) self.maptroid = Canvas(self.LFrame, bg='black', width=500, height=500) if self.selectTurn >= 0: self.printMap() self.maptroid.pack() self.LFrame.pack() def RightFrame(self, parent): self.RFrame = Frame(parent, width=130, height=500) if self.selectTurn >= 0: self.printInfo() self.FrameInfo = None self.updateT = True self.RFrame.pack() def setreadstate(self, readstate): self.readstate = readstate def addTurn(self, turnnumber, turnvalue): self.turns[turnnumber] = turnvalue self.updateGui(turnnumber) return self.etat def updateGui(self, turn): self.selectTurn = turn self.updateMap() self.updateInfo() def updateMap(self): self.maptroid.delete(ALL) self.printMap() def updateInfo(self): if self.FrameInfo: if self.updateT: self.frameT.destroy() self.printTurn() self.frameAnts.destroy() self.frameAnt.destroy() self.printAnts() self.updateT = True else: self.printInfo() def updateSpin_turn(self): turn = int(self.Spin_T.get()) self.updateT = False self.updateGui(turn) def validateTurn(self, event): try: turn = int(self.Spin_T.get()) except ValueError: turn = self.selectTurn if turn in self.turns.keys(): if turn != self.selectTurn: self.updateT = False self.updateGui(turn) else: turn = self.selectTurn def choiceAnt(self, event): i = self.listbox.curselection() id_a = self.listbox.get(i) self.frameAnt.destroy() self.printInfoAnt(int(id_a)) def printInfo(self): self.FrameInfo = Frame(self.RFrame) self.printTurn() self.printAnts() self.FrameInfo.pack() def printTurn(self): frameS = PanedWindow(self.FrameInfo, orient=HORIZONTAL) turns = Label(frameS, text="Tour :") self.var.set(str(self.selectTurn)) self.Spin_T = Spinbox(frameS, values=self.turns.keys(), command=self.updateSpin_turn, textvariable=self.var) self.Spin_T.bind('<Return>', self.validateTurn) turns.pack() self.Spin_T.pack() frameS.add(turns) frameS.add(self.Spin_T) frameS.pack() self.frameT = frameS def printAnts(self): frameAnts = Frame(self.FrameInfo) Text_A = Label(frameAnts, text="Fourmie :") s1 = Scrollbar(frameAnts) l1 = Listbox(frameAnts) id_ants = self.checkAnts() for i in id_ants: l1.insert(i, str(i)) s1.config(command=l1.yview) l1.config(yscrollcommand=s1.set) l1.bind('<ButtonRelease-1>', self.choiceAnt) self.listbox = l1 Text_A.pack(side=TOP) l1.pack(side=LEFT) s1.pack(side=RIGHT) frameAnts.pack() self.printInfoAnt(id_ants[0]) self.frameAnts = frameAnts def printInfoAnt(self, i): self.frameAnt = PanedWindow(self.FrameInfo, orient=VERTICAL) t_Ant = Label(self.frameAnt, text="Information Ant : %d" % (i)) (t_brain, t_energie, t_acide) = self.getInfoAnt(i) a_b = Label(self.frameAnt, text=t_brain) a_e = Label(self.frameAnt, text=t_energie) a_a = Label(self.frameAnt, text=t_acide) t_Ant.pack(side=TOP) self.frameAnt.add(t_Ant) self.frameAnt.add(a_b) self.frameAnt.add(a_e) self.frameAnt.add(a_a) self.frameAnt.pack() def printMap(self): turn = self.turns[self.selectTurn] # Information on this turn config = turn[0] Yants = turn[1] EAnts = turn[2] InitMap = turn[3] Cases = turn[4] (MaxX, MaxY, N) = InitMap self.MinX = 0 self.MinY = 0 MaxX_map = MaxX * self.caselength + (self.CaseMarge * 2) MaxY_map = MaxY * self.caselength + (self.CaseMarge * 2) #configure canvas self.maptroid.config(scrollregion=(0, 0, MaxX_map, MaxY_map)) x1 = self.CaseMarge y1 = self.CaseMarge x2 = MaxX * self.caselength + self.CaseMarge y2 = MaxY * self.caselength + self.CaseMarge self.maptroid.create_rectangle(x1, y1, x2, y2, fill="white") # affiche case for case in Cases: self.printCase(case) # affiche your ants for ant in Yants: # nb A : Your Ant 'ID X Y DX DY E A B' (id_a, x, y, dx, dy, e, a, b) = ant self.printAnt((x, y, dx, dy, b)) # affiche enemy ants for ant in EAnts: self.printAnt(ant) #to move map self.maptroid.bind('<ButtonPress-1>', self.grab) self.maptroid.bind('<B1-Motion>', self.drag) self.maptroid.bind('<MouseWheel>', self.mapZoom) self.maptroid.bind("<Button-4>", self.mapZoom) self.maptroid.bind("<Button-5>", self.mapZoom) def printCase(self, case): (x, y, c, s) = case (x1, y1, x2, y2) = self.getPoint(x, y) color = COLOR[c][s] if c % 2 == 0: self.maptroid.create_rectangle(x1, y1, x2, y2, fill=color) else: self.maptroid.create_rectangle(x1, y1, x2, y2, fill=COLOR[GRASS][s]) self.maptroid.create_oval(x1, y1, x2, y2, fill=color) def printAnt(self, ant): (x, y, dx, dy, brain) = ant (x1, y1, x2, y2) = self.getPoint(x, y) self.maptroid.create_oval(x1, y1, x2, y2, fill="red4") def getPoint(self, x, y): x1 = (x - self.MinX) * self.caselength + self.CaseMarge y1 = (y - self.MinY) * self.caselength + self.CaseMarge x2 = x1 + self.caselength y2 = y1 + self.caselength return (x1, y1, x2, y2) def grab(self, event): self._y = event.y self._x = event.x def drag(self, event): self.maptroid.yview('scroll', self._y - event.y, 'units') self.maptroid.xview('scroll', self._x - event.x, 'units') self._y = event.y self._x = event.x def mapZoom(self, event): # respond to Linux or Windows wheel event if event.num == 5 or event.delta == -120: self.caselength -= 5 self.caselength = max(self.caselength, 10) if event.num == 4 or event.delta == 120: self.caselength += 5 self.caselength = min(self.caselength, 40) self.CaseMarge = self.caselength self.updateMap() def getInfoAnt(self, id_ant): turn = self.turns[self.selectTurn] YAnt = turn[1] B_Text = "Brain :" E_Text = "Energie :" A_Text = "Acide :" for ant in YAnt: (id_a, x, y, dx, dy, e, a, b) = ant if b != 1: b = 0 if (id_ant == id_a): B_Text = "Brain : " + BRAIN[b] E_Text = "Energie : %d" % (e) A_Text = "Acide : %d" % (a) return (B_Text, E_Text, A_Text) def checkAnts(self): turn = self.turns[self.selectTurn] YAnt = turn[1] ants_id = [] for ant in YAnt: (id_a, x, y, dx, dy, e, a, b) = ant ants_id.append(id_a) return ants_id def myquit(self): self.etat = False if not self.readstate: self.quit()
class Temperatures(LabelFrame): def __init__(self, root, prtr, settings, log, *arg): LabelFrame.__init__(self, root, *arg, text="Temperatures") self.app = root self.printer = prtr self.settings = settings self.log = log l = Label(self, text="Extruder:", justify=LEFT) l.grid(row=1, column=1, sticky=W) self.statExt = Canvas(self, width=150, height=STAT_HEIGHT, bd=2, bg="white", relief=RIDGE) self.statExt.grid(row=1, column=2, columnspan=2) self.setStatus(self.statExt, UNKNOWN) self.bSetExt = Button(self, text="Set", width=4, command=self.doSetExt) self.bSetExt.grid(row=2, column=1, padx=2) self.spExtTemp = Spinbox(self, values=self.formatTemps(self.settings.extemps), width=12, justify=RIGHT) self.spExtTemp.grid(row=2, column=2) if self.settings.lastexttemp != None: self.spExtTemp.delete(0, END) self.spExtTemp.insert(0, self.settings.lastexttemp) self.spExtTemp.bind("<FocusOut>", self.valExtTemp) self.spExtTemp.bind("<Leave>", self.valExtTemp) self.bOffExt = Button(self, text="Off", width=4, command=self.doOffExt) self.bOffExt.grid(row=2, column=3, padx=2) self.frameExt = Frame(self) self.frameExt.grid(row=3, column=1, columnspan=3) self.legendExt = Canvas(self.frameExt, width=LEGEND_WIDTH, height=100, bd=2, bg="white", relief=RIDGE) self.legendExt.pack(side=LEFT, padx=0, pady=2) self.canvasExt = Canvas(self.frameExt, width=200, height=100, bd=2, bg="white", relief=RIDGE) self.canvasExt.pack(side=LEFT, padx=0, pady=2) self.drawExtAxes() self.extFan = IntVar() if self.settings.fanwithextruder: self.extFan.set(1) else: self.extFan.set(0) self.cb = Checkbutton(self, text="Fan on with extruder", variable=self.extFan, command=self.fanCheck) self.cb.grid(row=4, column=1, columnspan=3) self.forceExtTemp = IntVar() if self.settings.forceexttemp: self.forceExtTemp.set(1) else: self.forceExtTemp.set(0) self.forceExtTempCheck() self.bForceExt = Checkbutton(self, text="Force Ext Temp", variable=self.forceExtTemp, command=self.forceExtTempCheck) self.bForceExt.grid(row=5, column=1, columnspan=3) l = Label(self, text="Bed:", justify=LEFT) l.grid(row=6, column=1, sticky=W) self.statBed = Canvas(self, width=150, height=STAT_HEIGHT, bd=2, bg="white", relief=RIDGE) self.statBed.grid(row=6, column=2, columnspan=2) self.setStatus(self.statBed, UNKNOWN) self.bSetBed = Button(self, text="Set", width=4, command=self.doSetBed) self.bSetBed.grid(row=7, column=1, padx=2) self.spBedTemp = Spinbox(self, values=self.formatTemps(self.settings.bedtemps), width=12, justify=RIGHT) self.spBedTemp.grid(row=7, column=2) if self.settings.lastbedtemp != None: self.spBedTemp.delete(0, END) self.spBedTemp.insert(0, self.settings.lastbedtemp) self.spBedTemp.bind("<FocusOut>", self.valBedTemp) self.spBedTemp.bind("<Leave>", self.valBedTemp) self.bOffBed = Button(self, text="Off", width=4, command=self.doOffBed) self.bOffBed.grid(row=7, column=3, padx=2) self.frameBed = Frame(self) self.frameBed.grid(row=8, column=1, columnspan=3) self.legendBed = Canvas(self.frameBed, width=LEGEND_WIDTH, height=100, bd=2, bg="white", relief=RIDGE) self.legendBed.pack(side=LEFT, padx=0, pady=2) self.canvasBed = Canvas(self.frameBed, width=200, height=100, bd=2, bg="white", relief=RIDGE) self.canvasBed.pack(side=LEFT, padx=0, pady=2) self.drawBedAxes() self.dataBed = [] self.dataExt = [] self.forceBedTemp = IntVar() if self.settings.forcebedtemp: self.forceBedTemp.set(1) else: self.forceBedTemp.set(0) self.forceBedTempCheck() self.bForceBed = Checkbutton(self, text="Force Bed Temp", variable=self.forceBedTemp, command=self.forceBedTempCheck) self.bForceBed.grid(row=9, column=1, columnspan=3) self.monTemp = IntVar() self.monTemp.set(1) self.monCheck() self.cb = Checkbutton(self, text="Monitor temperatures", variable=self.monTemp, command=self.monCheck) self.cb.grid(row=10, column=1, columnspan=3) self.rptre = re.compile("ok *T:([0-9\.]+) *\/([0-9\.]+) *B:([0-9\.]+) *\/([0-9\.]+)") def fanCheck(self): self.settings.fanwithextruder = (self.extFan.get() == 1) self.settings.setModified() def forceBedTempCheck(self): if self.forceBedTemp.get() == 1: if not self.settings.forcebedtemp: self.settings.forcebedtemp = True self.settings.setModified() else: if self.settings.forcebedtemp: self.settings.forcebedtemp = False self.settings.setModified() def forceExtTempCheck(self): if self.forceExtTemp.get() == 1: if not self.settings.forceexttemp: self.settings.forceexttemp = True self.settings.setModified() else: if self.settings.forceexttemp: self.settings.forceexttemp = False self.settings.setModified() def monCheck(self): if self.monTemp.get() == 1: self.app.monitorTemp = True self.printer.tempcb = self.tempcb else: self.app.monitorTemp = False self.dataBed = [] self.canvasBed.delete("GRAPH") self.canvasBed.delete("TARGET") self.dataExt = [] self.canvasExt.delete("GRAPH") self.canvasExt.delete("TARGET") self.printer.tempcb = None self.setStatus(self.statExt, UNKNOWN) self.setStatus(self.statBed, UNKNOWN) def tempcb(self, l): m = self.rptre.search(l) t = m.groups() if len(t) != 4: return self.app.exttemp = float(t[0]) if self.settings.forceexttemp: tp = float(t[1]) if tp >= 0.05 and tp < self.app.exttarget: self.log.logMsg("Asserting hot end temperature of %.2f" % self.app.exttarget) self.printer.send_now("M104 S%s" % self.app.exttarget) else: self.app.exttarget = tp else: self.app.exttarget = float(t[1]) self.app.bedtemp = float(t[2]) if self.settings.forcebedtemp: tp = float(t[3]) if tp >= 0.05 and tp < self.app.bedtarget: self.log.logMsg("Asserting bed temperature of %.2f" % self.app.bedtarget) self.printer.send_now("M140 S%s" % self.app.bedtarget) else: self.app.bedtarget = tp else: self.app.bedtarget = float(t[3]) self.updateTempDisplay(float(t[2]), float(t[0])) def updateTempDisplay(self, tBed, tExt): self.addBedDatapoint(tBed) self.addExtDatapoint(tExt) if self.app.exttarget < 0.05: # unit is off if self.app.exttemp > 35: self.setStatus(self.statExt, COOLING) else: self.setStatus(self.statExt, COOL) else: # unit is on if self.app.exttarget - self.app.exttemp < 0.05: self.setStatus(self.statExt, HOT) else: self.setStatus(self.statExt, HEATING) if self.app.bedtarget < 0.05: # unit is off if self.app.bedtemp > 35: self.setStatus(self.statBed, COOLING) else: self.setStatus(self.statBed, COOL) else: # unit is on if self.app.bedtarget - self.app.bedtemp < 0.05: self.setStatus(self.statBed, HOT) else: self.setStatus(self.statBed, HEATING) def formatTemps(self, t): def cmptemp(a, b): ta = int(a.split()[0]) tb = int(b.split()[0]) return cmp(ta, tb) result = [x for x in t] return sorted(result, cmptemp) def doSetExt(self): if self.app.printerAvailable(cmd="M104"): if self.settings.fanwithextruder and self.app.FanSpeed != 255: if self.settings.forcefanspeed: self.logger.logMsg("Asserting fan speed of %d" % self.app.FanSpeed) else: self.app.toolbar.setFanSpeed(255) temp = self.spExtTemp.get().split(' ')[0] self.printer.send_now("M104 S%s" % temp) self.app.exttarget = float(temp) def valExtTemp(self, *arg): invalid = False try: choice = self.spExtTemp.get() x = int(choice.split(' ')[0]) except: self.log.logMsg("Value for Extruder temperature not a valid integer") invalid = True else: if x <=0 or x >MAXEXTTEMP: self.log.logMsg("Value for Extruder temperature out of range(0-%d" % MAXEXTTEMP) invalid = True if invalid: self.spExtTemp.delete(0, END) self.spExtTemp.insert(0, "%s" % self.formatTemps(self.settings.extemps)[0]) else: if choice not in self.settings.extemps: self.settings.extemps.append(choice) self.settings.setModified() self.spExtTemp.config(values=self.formatTemps(self.settings.extemps)) self.spExtTemp.delete(0, END) self.spExtTemp.insert(0, choice) if self.settings.lastexttemp != choice: self.settings.lastexttemp = choice self.settings.setModified() return True def doOffExt(self, *arg): if self.app.printerAvailable(cmd="M104"): if self.settings.fanwithextruder and self.app.FanSpeed != 0: if self.settings.forcefanspeed: self.logger.logMsg("Asserting fan speed of %d" % self.app.FanSpeed) else: self.app.toolbar.setFanSpeed(0) self.printer.send_now("M104 S0") def drawExtAxes(self): self.canvasExt.delete("AXES") for i in range(0, MAXEXTTEMP, 50): y = 100.0-(float(i)/MAXEXTTEMP*100.0) self.canvasExt.create_line(0, y, 200, y, fill="#C0C0C0", tags="AXES") self.legendExt.create_text(LEGEND_WIDTH, y+7, anchor=SE, tags="AXES", text="%3d" % i) def addExtDatapoint(self, t): c = (t/MAXEXTTEMP)*100.0 self.dataExt.append(c) while len(self.dataExt) >= MAXDATAPOINTS: del(self.dataExt[0]) self.canvasExt.delete("TARGET") self.canvasExt.delete("GRAPH") target = int((self.app.exttarget/MAXEXTTEMP)*100.0) if target != 0: self.canvasExt.create_line(0, 100-target, 200, 100-target, fill="blue", tags="TARGET") self.canvasExt.create_text(10, 100-target, anchor=SW, tags="TARGET", fill="blue", text="%3.3d" % int(self.app.exttarget)) start = MAXDATAPOINTS - len(self.dataExt) pTemp = 0 for i in range(start, MAXDATAPOINTS): if i != start: self.canvasExt.create_line(i*5, 100-pTemp, (i+1)*5, 100-self.dataExt[i-start], fill="red", tags="GRAPH") pTemp = self.dataExt[i-start] self.canvasExt.create_text(190, 100-c, anchor=SE, tags="GRAPH", fill="red", text="%3.3d" % int(t)) def setStatus(self, w, status): if status == UNKNOWN: c = "black" s = "??" elif status == HEATING: c = "orange" s = "heating" elif status == HOT: c = "red" s = "hot" elif status == COOLING: c = "blue" s = "cooling" elif status == COOL: c = "green" s = "cool" else: c = "black" s = "??" w.config(bg=c) w.delete(ALL) w.create_text(75, STAT_HEIGHT-5, text=s, fill="white") def doSetBed(self): if self.app.printerAvailable(cmd="M140"): temp = self.spBedTemp.get().split(' ')[0] self.printer.send_now("M140 S%s" % temp) self.app.bedtarget = float(temp) def valBedTemp(self, *arg): invalid = False try: choice = self.spBedTemp.get() x = int(choice.split(' ')[0]) except: self.log.logMsg("Value for Bed temperature not a valid integer") invalid = True else: if x <=0 or x >MAXEXTTEMP: self.log.logMsg("Value for Bed temperature out of range(0-%d" % MAXBEDTEMP) invalid = True if invalid: self.spBedTemp.delete(0, END) self.spBedTemp.insert(0, "%s" % self.formatTemps(self.settings.bedtemps)[0]) else: if choice not in self.settings.bedtemps: self.settings.bedtemps.append(choice) self.settings.setModified() self.spBedTemp.config(values=self.formatTemps(self.settings.bedtemps)) self.spBedTemp.delete(0, END) self.spBedTemp.insert(0, choice) if self.settings.lastbedtemp != choice: self.settings.lastbedtemp = choice self.settings.setModified() return True def doOffBed(self, *arg): if self.app.printerAvailable(cmd="M140"): self.printer.send_now("M140 S0") def addBedDatapoint(self, t): c = (t/MAXBEDTEMP)*100.0 self.dataBed.append(c) while len(self.dataBed) >= MAXDATAPOINTS: del(self.dataBed[0]) self.canvasBed.delete("TARGET") self.canvasBed.delete("GRAPH") target = int((self.app.bedtarget/MAXBEDTEMP)*100.0) if target != 0: self.canvasBed.create_line(0, 100-target, 200, 100-target, fill="blue", tags="TARGET") self.canvasBed.create_text(10, 100-target, anchor=SW, tags="TARGET", fill="blue", text="%3.3d" % int(self.app.bedtarget)) start = MAXDATAPOINTS - len(self.dataBed) pTemp = 0 for i in range(start, MAXDATAPOINTS): if i != start: self.canvasBed.create_line((i-1)*5, 100-pTemp, i*5, 100-self.dataBed[i-start], fill="red", tags="GRAPH") pTemp = self.dataBed[i-start] self.canvasBed.create_text(190, 100-c, anchor=SE, tags="GRAPH", fill="red", text="%3.3d" % int(t)) def drawBedAxes(self): self.canvasBed.delete("AXES") for i in range(0, MAXBEDTEMP, 50): y = 100.0-(float(i)/MAXBEDTEMP*100.0) self.canvasBed.create_line(0, y, 200, y, fill="#C0C0C0", tags="AXES") self.legendBed.create_text(LEGEND_WIDTH, y+7, anchor=SE, tags="AXES", text="%3d" % i)
def createWidgets(self): '''Create and align widgets''' top = self.winfo_toplevel() top.rowconfigure(0, weight=1) top.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) self.columnconfigure(0, weight=1) self.passwordout = StringVar() self.passwordout.set('- No password generated -') self.isnew = IntVar() ttitle = Label(self, text=versionStr, font=self.getFont(4)) wisnew = Checkbutton(self, height=2, font=self.getFont(), text=('This is a new password, that I have not ' 'used before'), variable=self.isnew, command=self.toggleCheck) tlabel = Label(self, text='Label', font=self.getFont(2)) tpasswordin1 = Label(self, text='Password', font=self.getFont(2)) tpasswordin2 = Label(self, text='Password (again)', font=self.getFont(2)) tlength = Label(self, text='Length', font=self.getFont(2)) talgorithm = Label(self, text='Algorithm', font=self.getFont(2)) tsequence = Label(self, text='Sequence #', font=self.getFont(2)) self.label = ttk.Combobox(self, width=27, font=self.getFont(), postcommand=self.filterLabels) self.passwordin1 = Entry(self, width=27, font=self.getFont(), show="*") self.passwordin2 = Entry(self, width=27, font=self.getFont(), show="*", state=DISABLED) length = Spinbox(self, width=3, font=self.getFont, from_=9, to=171, textvariable=self.lengthVar) self.algorithm = ttk.Combobox(self, width=27, font=self.getFont(), values=algos.algorithms) sequence = Spinbox(self, width=3, font=self.getFont, from_=1, to=sys.maxint, textvariable=self.sequenceVar) genbutton = Button(self, text="Generate password", font=self.getFont(), command=self.validateAndShow, default="active") clrbutton = Button(self, text="Clear fields", font=self.getFont(), command=self.clearIO) self.result = Entry(self, font=self.getFont(4), textvariable=self.passwordout, state="readonly", fg="black", readonlybackground="gray") # Keybindings self.passwordin1.bind('<Return>', lambda e: genbutton.invoke()) self.passwordin2.bind('<Return>', lambda e: genbutton.invoke()) length.bind('<Return>', lambda e: genbutton.invoke()) self.algorithm.bind('<Return>', lambda e: genbutton.invoke()) sequence.bind('<Return>', lambda e: genbutton.invoke()) self.master.bind('<Control-q>', lambda e: self.quit()) self.master.bind('<Escape>', lambda e: self.reset()) self.label.bind('<<ComboboxSelected>>', self.labelSelected) self.label.bind('<FocusOut>', self.labelFocusOut) # Layout widgets in a grid ttitle.grid(row=0, column=0, sticky=N + S + E + W, columnspan=2) wisnew.grid(row=1, column=0, sticky=N + S + E + W, columnspan=2) tlabel.grid(row=2, column=0, sticky=N + S + W) self.label.grid(row=2, column=1, sticky=N + S + E + W) tpasswordin1.grid(row=3, column=0, sticky=N + S + W) self.passwordin1.grid(row=3, column=1, sticky=N + S + E + W) tpasswordin2.grid(row=4, column=0, sticky=N + S + W) self.passwordin2.grid(row=4, column=1, sticky=N + S + E + W) tlength.grid(row=5, column=0, sticky=N + S + W) length.grid(row=5, column=1, sticky=N + S + E + W) talgorithm.grid(row=6, column=0, sticky=N + S + W) self.algorithm.grid(row=6, column=1, sticky=N + S + E + W) tsequence.grid(row=7, column=0, sticky=N + S + W) sequence.grid(row=7, column=1, sticky=N + S + E + W) clrbutton.grid(row=8, column=0, sticky=N + S + E + W, columnspan=2) genbutton.grid(row=9, column=0, sticky=N + S + E + W, columnspan=2) self.result.grid(row=10, column=0, sticky=N + S + E + W, columnspan=2) # Initial values self.algorithm.set(self.settings.algorithm) # Initially, set focus on self.label self.label.focus_set()
class ScanDialog(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.worker = None self.elapsed = 0 self.settings = Settings(self) # self.initUI() follows self.parent.title("Scan Images") self.pack(fill=BOTH, expand=1) r = 0 # current grid row Label(self, text="Name prefix:").grid(row=r, column=0) Label(self, text="Number suffix:").grid(row=r, column=1) r += 1 self.newName = StringVar() self.newName.set('Scan_') newName = Entry(self, textvariable=self.newName, width=60) newName.grid(row=1, column=0) newName.bind("<Return>", lambda event: self.scan()) newName.bind("<KP_Enter>", lambda event: self.scan()) newName.bind("<Escape>", lambda event: self.parent.destroy()) newName.focus_set() self.newNameEntry = newName self.numberSuffix = Spinbox(self, from_=1, to=999) self.numberSuffix.bind("<Return>", lambda event: self.scan()) self.numberSuffix.bind("<KP_Enter>", lambda event: self.scan()) self.numberSuffix.grid(row=r, column=1) r += 1 self.okButton = Button(self, text="Scan", command=self.scan, width=60, height=5) self.okButton.grid(row=r, column=0) cancelButton = Button(self, text="Cancel", command=self.parent.destroy) cancelButton.grid(row=r, column=1) r += 1 settings_panel = tk.Frame(self) panel = tk.Frame(settings_panel) tk.Label(panel, text="Paper Format").pack() tk.Radiobutton(panel, text="A4", value=1.0, variable=self.settings.scale).pack(anchor=tk.W) tk.Radiobutton(panel, text="A5", value=2 ** (-0.5), variable=self.settings.scale).pack(anchor=tk.W) tk.Radiobutton(panel, text="A6", value=0.5, variable=self.settings.scale).pack(anchor=tk.W) panel.pack(side=tk.LEFT, anchor=tk.N) panel = tk.Frame(settings_panel) tk.Label(panel, text="File Format").pack() tk.Radiobutton(panel, text="PNG", value='.png', variable=self.settings.extension).pack(anchor=tk.W) tk.Radiobutton(panel, text="JPG", value='.jpg', variable=self.settings.extension).pack(anchor=tk.W) panel.pack(side=tk.LEFT, anchor=tk.N) panel = tk.Frame(settings_panel) tk.Label(panel, text="Scan Mode").pack() tk.Radiobutton(panel, text="Color", value='color', variable=self.settings.scan_mode).pack(anchor=tk.W) tk.Radiobutton(panel, text="Gray", value='gray', variable=self.settings.scan_mode).pack(anchor=tk.W) tk.Radiobutton(panel, text="Lineart", value='lineart', variable=self.settings.scan_mode).pack(anchor=tk.W) panel.pack(side=tk.LEFT, anchor=tk.N) settings_panel.grid(row=r, column=0, columnspan=2) r += 1 self.statusLabel = Label(self, text="Idle") self.statusLabel.grid(row=r, column=0, columnspan=2) def _checkAlive(self): if self.worker is None: return if self.worker.is_alive(): self.after(100, self._checkAlive) self.elapsed += 1 self.statusLabel.config(text='Scanning, please wait... (%.1f s)' % (self.elapsed/10.0)) else: self.worker = None self.okButton.config(state=NORMAL) self.numberSuffix.invoke('buttonup') self.newNameEntry.focus_set() self.statusLabel.config(text='Idle (last scan: %.1f s)' % (self.elapsed/10.0)) def _ext(self): return self.settings.ext() def scan(self): target = '%s%03d%s' % (self.newName.get(), int(self.numberSuffix.get()), self._ext(), ) if os.path.exists(target): if not tkMessageBox.askokcancel(title='Scan Images', message='File exists. Overwrite?'): print 'Not scanning: %s - file exists!' % target new_name = self.newName.get() for i in xrange(int(self.numberSuffix.get()), 1000): new_target = '%s%03d.%s' % (new_name, int(self.numberSuffix.get()), self._ext(), ) if not os.path.exists(new_target): print 'Next available filename: %s' % (new_target, ) self.numberSuffix.delete(0, 'end') self.numberSuffix.insert(0, i) break return print "Scanning to filename '%s' ..." % (target, ) if s is None: print('No scanner present. Connect and restart application.') return if self.worker is None: self.worker = ScanWorker(target, self.settings) self.worker.start() self.elapsed = 0 self.after(100, self._checkAlive) self.okButton.config(state=DISABLED) self.statusLabel.config(text='Scanning, please wait...') else: print "Error - not started, worker exists."
class AntroidGUI(Tk): def __init__(self): Tk.__init__(self) self.protocol("WM_DELETE_WINDOW", self.myquit) self.etat = True self.readstate = True self.title("Antroid Map") self.turns = {} self.selectTurn = -1 self.caselength = 10 self.CaseMarge = 20 self.var = StringVar() self.initGUI() def initGUI(self): frame = Frame(self, width =630, height = 500) self.panel = PanedWindow(frame, orient=HORIZONTAL) self.LeftFrame(self.panel) self.RightFrame(self.panel) self.panel.add(self.LFrame) self.panel.add(self.RFrame) self.panel.pack() frame.pack() def LeftFrame(self, parent): self.LFrame=Frame(parent, width = 500, height = 500) self.maptroid = Canvas(self.LFrame,bg='black',width=500,height=500) if self.selectTurn >= 0: self.printMap() self.maptroid.pack() self.LFrame.pack() def RightFrame(self, parent): self.RFrame = Frame(parent, width = 130, height = 500) if self.selectTurn >= 0: self.printInfo() self.FrameInfo = None self.updateT = True self.RFrame.pack() def setreadstate(self, readstate): self.readstate = readstate def addTurn(self, turnnumber, turnvalue): self.turns[turnnumber] = turnvalue self.updateGui(turnnumber) return self.etat def updateGui(self, turn): self.selectTurn = turn self.updateMap() self.updateInfo() def updateMap(self): self.maptroid.delete(ALL) self.printMap() def updateInfo(self): if self.FrameInfo: if self.updateT: self.frameT.destroy() self.printTurn() self.frameAnts.destroy() self.frameAnt.destroy() self.printAnts() self.updateT = True else: self.printInfo() def updateSpin_turn(self): turn = int(self.Spin_T.get()) self.updateT = False self.updateGui(turn) def validateTurn(self, event): try: turn = int(self.Spin_T.get()) except ValueError: turn = self.selectTurn if turn in self.turns.keys(): if turn != self.selectTurn: self.updateT = False self.updateGui(turn) else: turn = self.selectTurn def choiceAnt(self,event): i = self.listbox.curselection() id_a = self.listbox.get(i) self.frameAnt.destroy() self.printInfoAnt(int(id_a)) def printInfo(self): self.FrameInfo=Frame(self.RFrame) self.printTurn() self.printAnts() self.FrameInfo.pack() def printTurn(self): frameS = PanedWindow(self.FrameInfo, orient=HORIZONTAL) turns = Label(frameS, text="Tour :") self.var.set(str(self.selectTurn)) self.Spin_T = Spinbox(frameS, values=self.turns.keys(), command = self.updateSpin_turn ,textvariable=self.var) self.Spin_T.bind('<Return>', self.validateTurn) turns.pack() self.Spin_T.pack() frameS.add(turns) frameS.add(self.Spin_T) frameS.pack() self.frameT = frameS def printAnts(self): frameAnts = Frame(self.FrameInfo) Text_A = Label(frameAnts, text="Fourmie :") s1 = Scrollbar(frameAnts) l1 = Listbox(frameAnts) id_ants = self.checkAnts() for i in id_ants: l1.insert(i, str(i)) s1.config(command = l1.yview) l1.config(yscrollcommand = s1.set) l1.bind('<ButtonRelease-1>',self.choiceAnt) self.listbox = l1 Text_A.pack(side = TOP) l1.pack(side = LEFT) s1.pack(side = RIGHT) frameAnts.pack() self.printInfoAnt(id_ants[0]) self.frameAnts = frameAnts def printInfoAnt(self, i): self.frameAnt = PanedWindow(self.FrameInfo, orient=VERTICAL) t_Ant = Label(self.frameAnt, text="Information Ant : %d" %(i)) (t_brain,t_energie,t_acide) = self.getInfoAnt(i) a_b = Label(self.frameAnt, text=t_brain) a_e = Label(self.frameAnt, text=t_energie) a_a = Label(self.frameAnt, text=t_acide) t_Ant.pack(side = TOP) self.frameAnt.add(t_Ant) self.frameAnt.add(a_b) self.frameAnt.add(a_e) self.frameAnt.add(a_a) self.frameAnt.pack() def printMap(self): turn = self.turns[self.selectTurn] # Information on this turn config = turn[0] Yants = turn[1] EAnts = turn[2] InitMap = turn[3] Cases = turn[4] (MaxX,MaxY,N) = InitMap self.MinX = 0 self.MinY = 0 MaxX_map = MaxX * self.caselength + (self.CaseMarge *2) MaxY_map = MaxY * self.caselength + (self.CaseMarge *2) #configure canvas self.maptroid.config(scrollregion=(0,0,MaxX_map,MaxY_map)) x1 = self.CaseMarge y1 = self.CaseMarge x2 = MaxX * self.caselength + self.CaseMarge y2 = MaxY * self.caselength +self.CaseMarge self.maptroid.create_rectangle(x1, y1, x2, y2, fill="white") # affiche case for case in Cases: self.printCase(case) # affiche your ants for ant in Yants: # nb A : Your Ant 'ID X Y DX DY E A B' (id_a,x,y,dx,dy,e,a,b) = ant self.printAnt((x,y,dx,dy,b)) # affiche enemy ants for ant in EAnts: self.printAnt(ant) #to move map self.maptroid.bind('<ButtonPress-1>',self.grab) self.maptroid.bind('<B1-Motion>',self.drag) self.maptroid.bind('<MouseWheel>',self.mapZoom) self.maptroid.bind("<Button-4>", self.mapZoom) self.maptroid.bind("<Button-5>", self.mapZoom) def printCase(self, case): (x,y,c,s) = case (x1, y1, x2, y2) = self.getPoint(x, y) color = COLOR[c][s] if c%2 == 0: self.maptroid.create_rectangle(x1, y1, x2, y2, fill=color) else: self.maptroid.create_rectangle(x1, y1, x2, y2, fill=COLOR[GRASS][s]) self.maptroid.create_oval(x1, y1, x2, y2, fill=color) def printAnt(self, ant): (x,y,dx,dy,brain) = ant (x1, y1, x2, y2) = self.getPoint(x, y) self.maptroid.create_oval(x1, y1, x2, y2, fill="red4") def getPoint(self, x, y): x1 = (x - self.MinX) * self.caselength + self.CaseMarge y1 = (y - self.MinY) * self.caselength + self.CaseMarge x2 = x1 + self.caselength y2 = y1 + self.caselength return (x1, y1, x2, y2) def grab(self,event): self._y = event.y self._x = event.x def drag(self, event): self.maptroid.yview('scroll',self._y-event.y,'units') self.maptroid.xview('scroll',self._x-event.x,'units') self._y = event.y self._x = event.x def mapZoom(self, event): # respond to Linux or Windows wheel event if event.num == 5 or event.delta == -120: self.caselength -= 5 self.caselength = max(self.caselength, 10) if event.num == 4 or event.delta == 120: self.caselength += 5 self.caselength = min(self.caselength, 40) self.CaseMarge = self.caselength self.updateMap() def getInfoAnt(self,id_ant): turn = self.turns[self.selectTurn] YAnt = turn[1] B_Text = "Brain :" E_Text = "Energie :" A_Text = "Acide :" for ant in YAnt: (id_a,x,y,dx,dy,e,a,b) = ant if b != 1 : b = 0 if(id_ant == id_a): B_Text = "Brain : " + BRAIN[b] E_Text = "Energie : %d" % (e) A_Text = "Acide : %d" % (a) return (B_Text,E_Text,A_Text) def checkAnts(self): turn = self.turns[self.selectTurn] YAnt = turn[1] ants_id = [] for ant in YAnt: (id_a,x,y,dx,dy,e,a,b) = ant ants_id.append(id_a) return ants_id def myquit(self): self.etat = False if not self.readstate: self.quit()