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

📄 joystick.py

📁 用wxPython编写GUI程序的样例代码
💻 PY
📖 第 1 页 / 共 3 页
字号:
#----------------------------------------------------------------------------
# Name:        Joystick.py
# Purpose:     Demonstrate use of wx.Joystick
#
# Author:      Jeff Grimmett (grimmtoo@softhome.net), adapted from original
#              .wdr-derived demo
#
# Created:     02-Jan-2004
# RCS-ID:      $Id: Joystick.py 30229 2004-11-01 19:39:09Z RD $
# Copyright:
# Licence:     wxWindows license
#----------------------------------------------------------------------------
#

import  math
import  wx

haveJoystick = True
if wx.Platform == "__WXMAC__":
    haveJoystick = False

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

# Once all supported versions of Python support 32-bit integers on all
# platforms, this can go up to 32.
MAX_BUTTONS = 16

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

class Label(wx.StaticText):
    # A derived StaticText that always aligns right and renders
    # in a bold font.
    def __init__(self, parent, label):
        wx.StaticText.__init__(self, parent, -1, label, style=wx.ALIGN_RIGHT)

        self.SetFont(
            wx.Font(
                parent.GetFont().GetPointSize(),
                parent.GetFont().GetFamily(),
                parent.GetFont().GetStyle(),
                wx.BOLD
                ))

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


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

        self.stick = stick
        size = (100,100)
        
        wx.Panel.__init__(self, parent, -1, size=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(*size)
        dc = wx.BufferedDC(None, self.buffer)
        self.DrawFace(dc)
        self.DrawJoystick(dc)
       

    def OnSize(self, event):
        # The face Bitmap init is done here, to make sure the buffer is always
        # the same size as the Window
        w, h  = self.GetClientSize()
        self.buffer = wx.EmptyBitmap(w,h)
        dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
        self.DrawFace(dc)
        self.DrawJoystick(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 DrawJoystick(self, dc):
        # draw the guage as a maxed square in the center of this window.
        w, h = self.GetClientSize()
        edgeSize = min(w, h)

        xorigin = (w - edgeSize) / 2
        yorigin = (h - edgeSize) / 2
        center = edgeSize / 2

        # Restrict our drawing activities to the square defined
        # above.
        dc.SetClippingRegion(xorigin, yorigin, edgeSize, edgeSize)

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

        dc.SetBrush(wx.Brush(wx.Colour(251, 252, 237)))
        dc.DrawRectangle(xorigin, yorigin, edgeSize, edgeSize)

        dc.SetPen(wx.Pen(wx.BLACK, 1, wx.DOT_DASH))

        dc.DrawLine(xorigin, yorigin + center, xorigin + edgeSize, yorigin + center)
        dc.DrawLine(xorigin + center, yorigin, xorigin + center, yorigin + edgeSize)

        if self.stick:
            # Get the joystick position as a float
            joyx =  float(self.stick.GetPosition().x)
            joyy =  float(self.stick.GetPosition().y)

            # Get the joystick range of motion
            xmin = self.stick.GetXMin()
            xmax = self.stick.GetXMax()
            if xmin < 0:
                xmax += abs(xmin)
                joyx += abs(xmin)
                xmin = 0
            xrange = max(xmax - xmin, 1)

            ymin = self.stick.GetYMin()
            ymax = self.stick.GetYMax()
            if ymin < 0:
                ymax += abs(ymin)
                joyy += abs(ymin)
                ymin = 0
            yrange = max(ymax - ymin, 1)

            # calc a ratio of our range versus the joystick range
            xratio = float(edgeSize) / xrange
            yratio = float(edgeSize) / yrange

            # calc the displayable value based on position times ratio
            xval = int(joyx * xratio)
            yval = int(joyy * yratio)

            # and normalize the value from our brush's origin
            x = xval + xorigin
            y = yval + yorigin

            # Now to draw it.
            dc.SetPen(wx.Pen(wx.RED, 2))
            dc.CrossHair(x, y)

        # Turn off drawing optimization
        dc.EndDrawing()


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


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

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

        self.stick = stick

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

        sizer = wx.BoxSizer(wx.VERTICAL)

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

        t = wx.StaticText(self, -1, "X - Y Axes", style = wx.ALIGN_CENTRE)
        t.SetFont(fn)
        sizer.Add(t, 0, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER | wx.ALIGN_CENTER_HORIZONTAL, 1)

        self.control = JoyGauge(self, self.stick)
        sizer.Add(self.control, 1, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER | wx.ALIGN_CENTER_HORIZONTAL, 1)

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

    def Update(self):
        self.control.Update()


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

class POVGauge(wx.Panel):
    #
    # Display the current postion of the POV control
    #
    def __init__(self, parent, stick):

        self.stick = stick
        self.size = (100, 100)
        self.avail = False
        self.fourDir = False
        self.cts = False

        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.DrawPOV(dc)


    def OnSize(self, event):
        # calculate the size of our display and make a buffer for it.
        w, h  = self.GetClientSize()
        s = min(w, h)
        self.size = (s, s)
        self.buffer = wx.EmptyBitmap(w,h)
        dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
        self.DrawFace(dc)
        self.DrawPOV(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 DrawPOV(self, dc):
        # draw the guage as a maxed circle in the center of this window.
        w, h = self.GetClientSize()
        diameter = min(w, h)

        xorigin = (w - diameter) / 2
        yorigin = (h - diameter) / 2
        xcenter = xorigin + diameter / 2
        ycenter = yorigin + diameter / 2

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

        # our 'raster'.
        dc.SetBrush(wx.Brush(wx.WHITE))
        dc.DrawCircle(xcenter, ycenter, diameter/2)
        dc.SetBrush(wx.Brush(wx.BLACK))
        dc.DrawCircle(xcenter, ycenter, 10)

        # fancy decorations
        dc.SetPen(wx.Pen(wx.BLACK, 1, wx.DOT_DASH))
        dc.DrawLine(xorigin, ycenter, xorigin + diameter, ycenter)
        dc.DrawLine(xcenter, yorigin, xcenter, yorigin + diameter)

        if self.stick:
            if self.avail:

                pos = -1

                # use the appropriate function to get the POV position
                if self.fourDir:
                    pos = self.stick.GetPOVPosition()

                if self.cts:
                    pos = self.stick.GetPOVCTSPosition()

                # trap invalid values
                if 0 <= pos <= 36000:
                    vector = 30
                else:
                    vector = 0

                # rotate CCW by 90 so that 0 is up.
                pos = (pos / 100) - 90

                # Normalize
                if pos < 0:
                    pos = pos + 360

                # Stolen from wx.lib.analogclock :-)
                radiansPerDegree = math.pi / 180
                pointX = int(round(vector * math.cos(pos * radiansPerDegree)))
                pointY = int(round(vector * math.sin(pos * radiansPerDegree)))

                # normalise value to match our actual center.
                nx = pointX + xcenter
                ny = pointY + ycenter

                # Draw the line
                dc.SetPen(wx.Pen(wx.BLUE, 2))
                dc.DrawLine(xcenter, ycenter, nx, ny)

                # And a little thing to show the endpoint
                dc.SetBrush(wx.Brush(wx.BLUE))
                dc.DrawCircle(nx, ny, 8)

        # Turn off drawing optimization
        dc.EndDrawing()


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


    def Calibrate(self):
        s = self.stick
        self.avail = s.HasPOV()
        self.fourDir = s.HasPOV4Dir()
        self.cts = s.HasPOVCTS()


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

class POVStatus(wx.Panel):
    #
    # Displays static info about the POV control
    #
    def __init__(self, parent, stick):

        self.stick = stick

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

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add((20,20))
        
        self.avail = wx.CheckBox(self, -1, "Available")
        sizer.Add(self.avail, 0, wx.ALL | wx.EXPAND | wx.ALIGN_LEFT, 2)

        self.fourDir = wx.CheckBox(self, -1, "4-Way Only")
        sizer.Add(self.fourDir, 0, wx.ALL | wx.EXPAND | wx.ALIGN_LEFT, 2)

        self.cts = wx.CheckBox(self, -1, "Continuous")
        sizer.Add(self.cts, 0, wx.ALL | wx.EXPAND | wx.ALIGN_LEFT, 2)

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

        # Effectively makes the checkboxes read-only.
        self.Bind(wx.EVT_CHECKBOX, self.Calibrate)


    def Calibrate(self, evt=None):
        s = self.stick
        self.avail.SetValue(s.HasPOV())
        self.fourDir.SetValue(s.HasPOV4Dir())
        self.cts.SetValue(s.HasPOVCTS())


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

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

        self.stick = stick

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

        sizer = wx.BoxSizer(wx.HORIZONTAL)

⌨️ 快捷键说明

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