⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 joystick.py

📁 用wxPython编写GUI程序的样例代码
💻 PY
📖 第 1 页 / 共 3 页
字号:
        gsizer = wx.BoxSizer(wx.VERTICAL)

        sizer.Add((25,25))
        
        fn = wx.Font(
                parent.GetFont().GetPointSize() + 3,
                parent.GetFont().GetFamily(),
                parent.GetFont().GetStyle(),
                wx.BOLD
                )
        t = wx.StaticText(self, -1, "POV Control", style = wx.ALIGN_CENTER)
        t.SetFont(fn)
        gsizer.Add(t, 0, wx.ALL | wx.EXPAND, 1)
        
        self.display = POVGauge(self, stick)
        gsizer.Add(self.display, 1, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 1)
        sizer.Add(gsizer, 1, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 1)
        
        self.status = POVStatus(self, stick)
        sizer.Add(self.status, 1, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER, 1)

        self.SetSizer(sizer)
        sizer.Fit(self)


    def Calibrate(self):
        self.display.Calibrate()
        self.status.Calibrate()


    def Update(self):
        self.display.Update()


#----------------------------------------------------------------------------

class LED(wx.Panel):
    def __init__(self, parent, number):

        self.state = -1
        self.size = (20, 20)
        self.number = number

        self.fn = wx.Font(
                parent.GetFont().GetPointSize() - 1,
                parent.GetFont().GetFamily(),
                parent.GetFont().GetStyle(),
                wx.BOLD
                )

        wx.Panel.__init__(self, parent, -1, size=self.size)

        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_SIZE, self.OnSize)
        self.Bind(wx.EVT_ERASE_BACKGROUND, lambda e: None)

        self.buffer = wx.EmptyBitmap(*self.size)
        dc = wx.BufferedDC(None, self.buffer)
        self.DrawFace(dc)
        self.DrawLED(dc)


    def OnSize(self, event):
        # calculate the size of our display.
        w, h  = self.GetClientSize()
        s = min(w, h)
        self.size = (s, s)
        self.buffer = wx.EmptyBitmap(*self.size)
        dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
        self.DrawFace(dc)
        self.DrawLED(dc)


    def DrawFace(self, dc):
        dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
        dc.Clear()


    def OnPaint(self, evt):
        # When dc is destroyed it will blit self.buffer to the window,
        # since no other drawing is needed we'll just return and let it
        # do it's thing
        dc = wx.BufferedPaintDC(self, self.buffer)


    def DrawLED(self, dc):
        # bitmap size
        bw, bh = self.size

        # center of bitmap
        center = bw / 2

        # calc the 0, 0 origin of the bitmap
        xorigin = center - (bw / 2)
        yorigin = center - (bh / 2)

        # Optimize drawing a bit (for Win)
        dc.BeginDrawing()

        # our 'raster'.
        if self.state == 0:
            dc.SetBrush(wx.Brush(wx.RED))
        elif self.state == 1:
            dc.SetBrush(wx.Brush(wx.GREEN))
        else:
            dc.SetBrush(wx.Brush(wx.BLACK))

        dc.DrawCircle(center, center, bw/2)

        txt = str(self.number)

        # Set the font for the DC ...
        dc.SetFont(self.fn)
        # ... and calculate how much space our value
        # will take up.
        fw, fh = dc.GetTextExtent(txt)

        # Calc the center of the LED, and from that
        # derive the origin of our value.
        tx = center - (fw/2)
        ty = center - (fh/2)

        # I draw the value twice so as to give it a pseudo-shadow.
        # This is (mostly) because I'm too lazy to figure out how
        # to blit my text onto the gauge using one of the logical
        # functions. The pseudo-shadow gives the text contrast
        # regardless of whether the bar is under it or not.
        dc.SetTextForeground(wx.WHITE)
        dc.DrawText(txt, tx, ty)

        # Turn off drawing optimization
        dc.EndDrawing()


    def Update(self):
        dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
        self.DrawFace(dc)
        self.DrawLED(dc)


#----------------------------------------------------------------------------

class JoyButtons(wx.Panel):
    def __init__(self, parent, stick):

        self.stick = stick
        self.leds = {}

        wx.Panel.__init__(self, parent, -1)

        tsizer = wx.BoxSizer(wx.VERTICAL)

        fn = wx.Font(
                parent.GetFont().GetPointSize() + 3,
                parent.GetFont().GetFamily(),
                parent.GetFont().GetStyle(),
                wx.BOLD
                )

        t = wx.StaticText(self, -1, "Buttons", style = wx.ALIGN_LEFT)
        t.SetFont(fn)
        tsizer.Add(t, 0, wx.ALL | wx.EXPAND | wx.ALIGN_LEFT, 1)

        sizer = wx.FlexGridSizer(4, 16, 2, 2)

        fn.SetPointSize(parent.GetFont().GetPointSize() + 1)

        for i in range(0, MAX_BUTTONS):
            t = LED(self, i)
            self.leds[i] = t
            sizer.Add(t, 1, wx.ALL|wx.ALIGN_CENTER|wx.ALIGN_CENTER_VERTICAL, 1)
            sizer.AddGrowableCol(i)

        tsizer.Add(sizer, 1, wx.ALL | wx.EXPAND | wx.ALIGN_LEFT, 1)

        self.SetSizer(tsizer)
        tsizer.Fit(self)

    def Calibrate(self):
        for i in range(0, MAX_BUTTONS):
            self.leds[i].state = -1

        t = self.stick.GetNumberButtons()

        for i in range(0, t):
            self.leds[i].state = 0

    def Update(self):
        t = self.stick.GetButtonState()

        for i in range(0, MAX_BUTTONS):
            if self.leds[i].state == 1:
                self.leds[i].state = 0

            if (t & (1<<i)):
                self.leds[i].state = 1

            self.leds[i].Update()


#----------------------------------------------------------------------------

class InfoPanel(wx.Panel):
    def __init__(self, parent, stick):

        self.stick = stick

        wx.Panel.__init__(self, parent, -1)

        sizer = wx.GridBagSizer(1, 1)

        sizer.Add(Label(self, 'Mfr ID: '), (0, 0), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_RIGHT, 2)
        self.MfgID = wx.TextCtrl(self, -1, value='', size=(45, -1), style=wx.TE_READONLY)
        sizer.Add(self.MfgID, (0, 1), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_LEFT, 2)

        sizer.Add(Label(self, 'Prod Name: '), (0, 2), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_RIGHT, 2)
        self.ProdName = wx.TextCtrl(self, -1, value='', style=wx.TE_READONLY)
        sizer.Add(self.ProdName, (0, 3), (1, 3), wx.ALL | wx.GROW | wx.ALIGN_LEFT, 2)

        sizer.Add(Label(self, 'Threshold: '), (0, 6), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_RIGHT, 2)
        self.Threshold = wx.TextCtrl(self, -1, value='', size=(45, -1), style=wx.TE_READONLY)
        sizer.Add(self.Threshold, (0, 7), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_LEFT, 2)

        #----------------------------------------------------------------------------
        b = wx.Button(self, -1, "Calibrate")
        sizer.Add(b, (1, 0), (2, 2), wx.ALL | wx.ALIGN_CENTER, 2)

        sizer.Add(Label(self, '# of Sticks: '), (1, 2), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_RIGHT, 2)
        self.NumJoysticks = wx.TextCtrl(self, -1, value='', size=(45, -1), style=wx.TE_READONLY)
        sizer.Add(self.NumJoysticks, (1, 3), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_LEFT, 2)

        sizer.Add(Label(self, '# of Axes: '), (1, 4), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_RIGHT, 2)
        self.NumAxis = wx.TextCtrl(self, -1, value='', size=(45, -1), style=wx.TE_READONLY)
        sizer.Add(self.NumAxis, (1, 5), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_LEFT, 2)

        sizer.Add(Label(self, 'Max # Axes: '), (1, 6), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_RIGHT, 2)
        self.MaxAxis = wx.TextCtrl(self, -1, value='', size=(45, -1), style=wx.TE_READONLY)
        sizer.Add(self.MaxAxis, (1, 7), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_LEFT, 2)

        #----------------------------------------------------------------------------

        sizer.Add(Label(self, 'Polling -- '), (2, 3), (1, 1), wx.ALL | wx.GROW, 2)

        sizer.Add(Label(self, 'Min: '), (2, 4), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_RIGHT, 2)
        self.PollMin = wx.TextCtrl(self, -1, value='', size=(45, -1), style=wx.TE_READONLY)
        sizer.Add(self.PollMin, (2, 5), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_LEFT, 2)

        sizer.Add(Label(self, 'Max: '), (2, 6), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_RIGHT, 2)
        self.PollMax = wx.TextCtrl(self, -1, value='', size=(45, -1), style=wx.TE_READONLY)
        sizer.Add(self.PollMax, (2, 7), (1, 1), wx.ALL | wx.GROW | wx.ALIGN_LEFT, 2)

        #----------------------------------------------------------------------------

        self.SetSizer(sizer)
        sizer.Fit(self)


    def Calibrate(self):
        if not self.stick:
            return

        s = self.stick

        self.MfgID.SetValue(str(s.GetManufacturerId()))
        self.ProdName.SetValue(str(s.GetProductName()))
        self.Threshold.SetValue(str(s.GetMovementThreshold()))
        self.NumJoysticks.SetValue(str(s.GetNumberJoysticks()))
        self.NumAxis.SetValue(str(s.GetNumberAxes()))
        self.MaxAxis.SetValue(str(s.GetMaxAxes()))
        self.PollMin.SetValue(str(s.GetPollingMin()))
        self.PollMax.SetValue(str(s.GetPollingMax()))


#----------------------------------------------------------------------------

class AxisBar(wx.Gauge):
    #
    # This class allows us to use a wx.Gauge to display the axis value
    # with a fancy label overlayed onto the guage itself. Two values are
    # used to do things: first of all, since the gauge is limited to
    # positive numbers, the scale is fixed at 0 to 1000. We will receive
    # an adjusted value to use to render the gauge itself. The other value
    # is a raw value and actually reflects the value from the joystick itself,
    # which is then drawn over the gauge.
    #
    def __init__(self, parent):
        wx.Gauge.__init__(self, parent, -1, 1000, size=(-1, 20), style = wx.GA_HORIZONTAL | wx.GA_SMOOTH )

        # This is the value we will display.
        self.rawvalue = 0

        self.SetBackgroundColour('light blue')
        self.SetForegroundColour('orange')

        # Capture paint events for purpose of updating
        # the displayed value.
        self.Bind(wx.EVT_PAINT, self.onPaint)

    def Update(self, value, rawvalue):
        # Updates the gauge itself, sets the raw value for
        # the next EVT_PAINT
        self.SetValue(value)
        self.rawvalue = rawvalue

    def onPaint(self, evt):
        # Must always create a PaintDC when capturing
        # an EVT_PAINT event
        self.ShowValue(wx.PaintDC(self), evt)

    def ShowValue(self, dc, evt):
        # This method handles actual painting of and drawing
        # on the gauge.

        # Clear out the gauge
        dc.Clear()
        # and then carry out business as usual
        wx.Gauge.OnPaint(self, evt)

        # This is the size available to us.
        w, h = dc.GetSize()

        # This is what we will overlay on the gauge.
        # It reflects the actual value received from the
        # wx.Joystick.
        txt = str(self.rawvalue)

        # Copy the default font, make it bold.
        fn = wx.Font(
                self.GetFont().GetPointSize(),
                self.GetFont().GetFamily(),
                self.GetFont().GetStyle(),
                wx.BOLD
                )

        # Set the font for the DC ...
        dc.SetFont(fn)
        # ... and calculate how much space our value
        # will take up.
        fw, fh = dc.GetTextExtent(txt)

        # Calc the center of the gauge, and from that
        # derive the origin of our value.
        center = w / 2
        tx = center - (fw/2)

        center = h / 2
        ty = center - (fh/2)

        # I draw the value twice so as to give it a pseudo-shadow.
        # This is (mostly) because I'm too lazy to figure out how
        # to blit my text onto the gauge using one of the logical
        # functions. The pseudo-shadow gives the text contrast
        # regardless of whether the bar is under it or not.
        dc.SetTextForeground(wx.BLACK)
        dc.DrawText(txt, tx, ty)

        dc.SetTextForeground('white')
        dc.DrawText(txt, tx-1, ty-1)


#----------------------------------------------------------------------------

class Axis(wx.Panel):
    #
    # This class is a container for the min, max, and current
    # values of the joystick axis in question. It contains
    # also special features to render a 'dummy' if the axis
    # in question is not available.
    #
    def __init__(self, parent, token, stick):

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -