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 + -
显示快捷键?