Пример #1
0
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
Пример #2
0
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")
Пример #3
0
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()
Пример #5
0
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)
Пример #6
0
    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()
Пример #7
0
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()