spokepov.py
来自「旋转16个LED灯控制程序」· Python 代码 · 共 1,102 行 · 第 1/3 页
PY
1,102 行
filemenu.Append(wx.ID_EXIT, "E&xit", "Exit") # bind the menu events to event handlers # import image self.Bind(wx.EVT_MENU, self.OnImportBMP, id=1) self.Bind(wx.EVT_MENU, self.OnImportBMPRect, id=2) # Exit self.Bind(wx.EVT_MENU, self.OnTimeToClose, id=wx.ID_EXIT) # set rotation self.Bind(wx.EVT_MENU, self.OnSetRotation, id=5) # save self.Bind(wx.EVT_MENU, self.OnSave, id=3) self.Bind(wx.EVT_MENU, self.OnSaveAs, id=4) self.Bind(wx.EVT_MENU, self.OnOpen, id=0) # and put the menu on the menubar menuBar.Append(filemenu, "&File") self.SetMenuBar(menuBar) self.CreateStatusBar() # Now create the Panel to put the other controls on. mainpanel = wx.Panel(self) mainpanelsizer = wx.BoxSizer(wx.VERTICAL) # a wheelpanel self.wheel = WheelPanel(mainpanel) self.wheel.SetSize((WHEEL_W,WHEEL_H)) mainpanelsizer.Add(self.wheel, 0, wx.ALL | wx.ALIGN_CENTER, 0) lowerpanel = wx.Panel(mainpanel) lowerpanelsizer = wx.BoxSizer(wx.HORIZONTAL) # create 3 buttons: read, write, verify buttonpanel = wx.Panel(lowerpanel) buttonpanelsizer = wx.GridSizer(1, 3, 5, 10) readbutton = wx.Button(buttonpanel, -1, "Read") writebutton = wx.Button(buttonpanel, -1, "Write") verifybutton = wx.Button(buttonpanel, -1, "Verify") self.Bind(wx.EVT_BUTTON, self.OnReadButton, readbutton); self.Bind(wx.EVT_BUTTON, self.OnWriteButton, writebutton); self.Bind(wx.EVT_BUTTON, self.OnVerifyButton, verifybutton); buttonpanelsizer.Add(readbutton, 0, wx.ALL, 0) buttonpanelsizer.Add(writebutton, 0, wx.ALL, 0) buttonpanelsizer.Add(verifybutton, 0, wx.ALL, 0) buttonpanel.SetSizer(buttonpanelsizer) buttonpanel.Layout() lowerpanelsizer.Add(buttonpanel, 1, wx.EXPAND|wx.ALL, 10) radiopanel = wx.Panel(lowerpanel) radiopanelsizer = wx.FlexGridSizer(1, 2, 5, 5) radiobuttonpanel = wx.Panel(radiopanel) radiobuttonpanelsizer = wx.FlexGridSizer(2, 1, 5, 5) self.mirror_yes = wx.RadioButton(radiobuttonpanel, -1, " Yes ", style = wx.RB_GROUP ) self.mirror_no = wx.RadioButton(radiobuttonpanel, -1, " No " ) radiobuttonpanelsizer.Add(self.mirror_yes, 0, wx.ALL, 0) radiobuttonpanelsizer.Add(self.mirror_no, 0, wx.ALL, 0) radiobuttonpanel.SetSizer(radiobuttonpanelsizer) radiobuttonpanel.Layout() label = wx.StaticText(radiopanel, -1, "Mirror image on other side?") radiopanelsizer.Add(label, 0, wx.ALIGN_CENTRE|wx.ALL, 5) radiopanelsizer.Add(radiobuttonpanel, 0, wx.ALIGN_CENTRE|wx.ALL, 5) radiopanel.SetSizer(radiopanelsizer) radiopanel.Layout() lowerpanelsizer.Add(radiopanel, 1, wx.EXPAND|wx.ALL, 0) lowerpanel.SetSizer(lowerpanelsizer) lowerpanelsizer.Layout(); mainpanelsizer.Add(lowerpanel, 0, wx.ALL | wx.ALIGN_CENTER, 10) mainpanel.SetSizer(mainpanelsizer) mainpanel.Layout() self.wheel.UpdateBackground() # create the doublebuffered background self.wheel.Draw() def OnSetRotation(self, evt): spov = SpokePOVComm() try: offset = spov.read_eeprom(0x8000) self.SetStatusText("Read rotation offset successfully") except IOError: self.SetStatusText("IO ERROR: Could not read rotation offset!") return dlg = SetRotationDialog(self, -1, "Set Rotation Offset", size=(350, 200), #style = wxCAPTION | wxSYSTEM_MENU | wxTHICK_FRAME style = wx.DEFAULT_DIALOG_STYLE, offset=offset ) dlg.CenterOnScreen() # this does not return until the dialog is closed. val = dlg.ShowModal() dlg.Destroy() def OnVerifyButton(self, evt): global model failed = False spov = SpokePOVComm() try: i = 0 lasttime = time.time(); while (i < (ROWS_PER_WHEEL * 4)): foo16 = spov.read_eeprom16(i) self.SetStatusText('Reading address '+str(i)) for j in range(0, 16): foo = ~(foo16[j]) for y in range(int((i+j)%4)*8, min(30, int((i+j)%4)*8+8) ): if (model[(int((i+j)/4), y)] != (foo >> 7) & 0x1): self.SetStatusText("Verification Failed!") return foo = foo << 1 i += 16 if (not ((self.mirror_yes.GetValue() == 0) and (spov.read_eeprom(EEPROM_MIRROR) == 0))): self.SetStatusText("Verification Failed!") return self.SetStatusText("Verification sucessful!") except IOError: self.SetStatusText("IO ERROR: died at address %d" % i) def OnReadButton(self, evt): global model read = WheelModel() spov = SpokePOVComm() try: i = 0 lasttime = time.time(); while i < (ROWS_PER_WHEEL * 4): foo16 = spov.read_eeprom16(i) self.SetStatusText('Reading address '+str(i)) for j in range(0, 16): foo = ~(foo16[j]) for y in range(int((i+j)%4)*8, min(30, int((i+j)%4)*8+8) ): read[(int((i+j)/4), y)] = (foo >> 7) & 0x1 foo = foo << 1 i += 16 # read the mirror value self.mirror_yes.SetValue(spov.read_eeprom(EEPROM_MIRROR)) self.mirror_no.SetValue(not spov.read_eeprom(EEPROM_MIRROR)) self.SetStatusText("Took %2.1f seconds" % (time.time() - lasttime)) model = read self.wheel.Draw() except IOError: self.SetStatusText("IO ERROR: died at address %d" % i) def OnWriteButton(self, evt): global model spov = SpokePOVComm() try: i = 0 lasttime = time.time(); while i < (ROWS_PER_WHEEL * 4): buff16 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] for col in range(0, 4): for row in range(0, 4): foo = 0 for y in range(row*8, min(30, (row+1)*8) ): if (y < (30-num_leds)): continue foo = foo << 1 foo |= model[((i/4)+col, y-(30-num_leds))] & 0x1 # ignore the first two bits (they are not displayed) if (row == 3): foo <<= 2 buff16[col*4+row] = ~foo self.SetStatusText('Writing address '+str(i)) spov.write_eeprom16(i, buff16) i += 16 # write the mirror value if (self.mirror_yes.GetValue()): spov.write_eeprom(EEPROM_MIRROR, 1) else: spov.write_eeprom(EEPROM_MIRROR, 0) self.SetStatusText("Took %2.1f seconds" % (time.time() - lasttime)) except IOError: self.SetStatusText("IO ERROR: died at address %d" % i) def OnImportBMP(self, evt): #print("importing...") dialog = wx.FileDialog(self, "Choose an image to import...", # title "", "", # no defaults "BMP files (*.bmp)|*.bmp", # BMP only wx.OPEN); # open a file if (dialog.ShowModal() == wx.ID_CANCEL): return # canceled, bail # ok they opened a file... # turn into an Image im = wx.Image(dialog.GetPath()) #print im.GetWidth(), im.GetHeight() self.filename = None self.SetTitle("pySpokePOV") self.wheel.setImage(im) # RJW - 06/27/06 - version of load file that maps a rectangle onto the # circle. Useful for character bitmaps def OnImportBMPRect(self, evt): #print("importing...") dialog = wx.FileDialog(self, "Choose an image to import (map rectangle to circle)...", # title "", "", # no defaults "BMP file (*.bmp)|*.bmp", # BMP only wx.OPEN); # open a file if (dialog.ShowModal() == wx.ID_CANCEL): return # canceled, bail # ok they opened a file... # turn into an Image im = wx.Image(dialog.GetPath()) #print im.GetWidth(), im.GetHeight() self.filename = None self.SetTitle("pySpokePOV") self.wheel.setImageRect(im) # RJW - 06/27/06 - said BMP, should say DAT... def OnOpen(self, evt): global model dialog = wx.FileDialog(self, "Choose an SpokePOV image to open...", # title "", "", # no defaults "Data file (*.dat)|*.dat", # DAT only wx.OPEN); # open a file if (dialog.ShowModal() == wx.ID_CANCEL): return self.filename = dialog.GetPath(); self.SetTitle("pySpokePOV "+self.filename) try: model = pickle.load(open(self.filename)) except IOError: self.SetStatus("Error reading file!") model.set_changed(True) self.wheel.UpdateForegroundMask() self.wheel.Draw() def OnSave(self, evt): global model if (self.filename == None): dialog = wx.FileDialog(self, "Save SpokePov image...", # title "", "", # no defaults "Data file (*.dat)|*.dat", # BMP only wx.SAVE); # open a file if (dialog.ShowModal() == wx.ID_CANCEL): return # canceled, bail # ok they saved self.filename = dialog.GetPath(); self.SetTitle("pySpokePOV "+self.filename) try: f = open(self.filename, 'w') pickle.dump(model, f) f.close() except IOError: self.SetStatus("Error writing to file!") def OnSaveAs(self, evt): global model dialog = wx.FileDialog(self, "Save SpokePov image as...", # title "", "", # no defaults "Data file (*.dat)|*.dat", # BMP only wx.SAVE); # open a file if (dialog.ShowModal() == wx.ID_CANCEL): return # canceled, bail # ok they saved self.filename = dialog.GetPath(); self.SetTitle("pySpokePOV "+self.filename) try: f = open(self.filename, 'w') pickle.dump(model, f) f.close() except IOError: self.SetStatus("Error writing to file!") def OnTimeToClose(self, evt): """Event handler for the button click.""" self.Close()##############################################33# wrapper####class SpokeSoft(wx.App): def OnInit(self): frame = SpokeSoftFrame(None, "pySpokePOV") self.SetTopWindow(frame) frame.Show(True) return True def main(argv=None): global config, hubsize, num_leds # read configuration try: config = ConfigParser.SafeConfigParser() except: # Assume the problem is a python version older than 2.3 # (which is when SafeConfigParser got added) config = ConfigParser.ConfigParser() config.read("SpokePOV.cfg") try: # 4 LEDs per inch hubsize = float(config.get('preferences', 'hubsize')) * 4 except ConfigParser.NoOptionError: hubsize = 4*1.5 # default is 2" diameter try: num_leds = int(config.get('preferences', 'num_leds')) except ConfigParser.NoOptionError: num_leds = 30 app = SpokeSoft(redirect=False) if argv is None: argv = sys.argv app.MainLoop()if __name__ == '__main__': # Redirect stdout/stderr# sys.stderr = open("stderr.log", "w")# sys.stdout = open("stdout.log", "w") sys.exit(main())
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?