Sophie

Sophie

distrib > Fedora > 17 > i386 > media > updates > by-pkgid > 9c24ddaa7665ff7a0443b0410b953bbd > files > 43

PyQwt-devel-5.2.0-20.fc17.i686.rpm

#!/usr/bin/env python

# The Python version of qwt-*/examples/dials

# for debugging, requires: python configure.py --trace ...
if 0:
    import sip
    sip.settracemask(0x3f)

import math
import random
import sys
from PyQt4 import Qt
import PyQt4.Qwt5 as Qwt


def enumList(enum, sentinel):
    '''
    '''
    return [enum(i) for i in range(sentinel)]

colorGroupList = enumList(
    Qt.QPalette.ColorGroup, Qt.QPalette.NColorGroups)
colorRoleList = enumList(
    Qt.QPalette.ColorRole, Qt.QPalette.NColorRoles)
handList  = enumList(
    Qwt.QwtAnalogClock.Hand, Qwt.QwtAnalogClock.NHands)


class CompassGrid(Qt.QFrame):

    def __init__(self, *args):
        Qt.QFrame.__init__(self, *args)

        palette = self.palette()
        palette.setColor(self.backgroundRole(), Qt.Qt.gray)
        self.setPalette(palette)
        
        layout = Qt.QGridLayout(self)

        for i in xrange(6):
            layout.addWidget(self.__createCompass(i), i / 3, i % 3)

        for i in xrange(layout.columnCount()):
            layout.setColumnStretch(i, 1)

    # __init__()
    
    def __createCompass(self, pos):

        palette = Qt.QPalette()
        for colorRole in colorRoleList:
            palette.setColor(colorRole, Qt.QColor())

        palette.setColor(
            Qt.QPalette.Base,
            self.palette().color(self.backgroundRole()).light(120))
        palette.setColor(
            Qt.QPalette.Foreground,
            palette.color(Qt.QPalette.Base))

        compass = Qwt.QwtCompass()
        compass.setLineWidth(4)
        if pos < 3:
            compass.setFrameShadow(Qwt.QwtCompass.Sunken)
        else:
            compass.setFrameShadow(Qwt.QwtCompass.Raised)

        if pos == 0:
            compass.setMode(Qwt.QwtCompass.RotateScale)
            rose = Qwt.QwtSimpleCompassRose(16, 2)
            rose.setWidth(0.15)
            compass.setRose(rose)
        elif pos == 1:
            compass.setLabelMap({0.0: "N",
                                 90.0: "E",
                                 180.0: "S",
                                 270.0: "W"})
            rose = Qwt.QwtSimpleCompassRose(4, 1)
            compass.setRose(rose)
            compass.setNeedle(
                Qwt.QwtCompassWindArrow(Qwt.QwtCompassWindArrow.Style2))
            compass.setValue(60.0)
        elif pos == 2:
            palette.setColor(Qt.QPalette.Base, Qt.Qt.darkBlue)
            palette.setColor(Qt.QPalette.Foreground,
                             Qt.QColor(Qt.Qt.darkBlue).dark(120))
            palette.setColor(Qt.QPalette.Text, Qt.Qt.white)
            compass.setScaleTicks(1, 1, 3)
            compass.setScale(36, 5, 0)
            compass.setNeedle(Qwt.QwtCompassMagnetNeedle(
                Qwt.QwtCompassMagnetNeedle.ThinStyle))
            compass.setValue(220.0)
        elif pos == 3:
            palette.setColor(Qt.QPalette.Base,
                             self.palette().color(self.backgroundRole()))
            palette.setColor(Qt.QPalette.Foreground, Qt.Qt.blue)
            compass.setLineWidth(0)
            compass.setScaleOptions(Qwt.QwtDial.ScaleBackbone
                                    | Qwt.QwtDial.ScaleTicks
                                    | Qwt.QwtDial.ScaleLabel)
            compass.setScaleTicks(0, 0, 3)
            compass.setLabelMap({  0.0:   '0',
                                  60.0:  '60',
                                 120.0: '120',
                                 180.0: '180',
                                 240.0: '240',
                                 320.0: '320'})
            compass.setScale(36, 5, 0)
            compass.setNeedle(Qwt.QwtDialSimpleNeedle(
                Qwt.QwtDialSimpleNeedle.Ray,
                False,
                Qt.Qt.white))
            compass.setOrigin(220.0)
            compass.setValue(20.0)
        elif pos == 4:
            compass.setScaleTicks(0, 0, 3)
            compass.setNeedle(Qwt.QwtCompassMagnetNeedle(
                Qwt.QwtCompassMagnetNeedle.TriangleStyle,
                Qt.Qt.white,
                Qt.Qt.red))
            compass.setValue(220.0)
        elif pos == 5:
            palette.setColor(Qt.QPalette.Foreground, Qt.Qt.black)
            compass.setNeedle(Qwt.QwtDialSimpleNeedle(
                Qwt.QwtDialSimpleNeedle.Ray,
                False,
                Qt.Qt.yellow))
            compass.setValue(315.0)

        newPalette = compass.palette()
        for colorRole in colorRoleList:
            if palette.color(colorRole).isValid():
                for colorGroup in colorGroupList:
                    newPalette.setColor(
                        colorGroup, colorRole, palette.color(colorRole))

        for colorGroup in colorGroupList:
            light = newPalette.color(
                colorGroup, Qt.QPalette.Base).light(170)
            dark = newPalette.color(
                colorGroup, Qt.QPalette.Base).dark(170)
            if compass.frameShadow() == Qwt.QwtDial.Raised:
                mid = newPalette.color(
                    colorGroup, Qt.QPalette.Base).dark(110)
            else:
                mid = newPalette.color(
                    colorGroup, Qt.QPalette.Base).light(110)

            newPalette.setColor(colorGroup, Qt.QPalette.Dark, dark)
            newPalette.setColor(colorGroup, Qt.QPalette.Mid, mid)
            newPalette.setColor(colorGroup, Qt.QPalette.Light, light)

        compass.setPalette(newPalette)

        return compass

    # __createCompass()

# class CompassGrid


class SpeedoMeter(Qwt.QwtDial):

    def __init__(self, *args):
        Qwt.QwtDial.__init__(self, *args)
        self.__label = 'km/h'
        self.setWrapping(False)
        self.setReadOnly(True)

        self.setOrigin(135.0)
        self.setScaleArc(0.0, 270.0)

        self.setNeedle(Qwt.QwtDialSimpleNeedle(
            Qwt.QwtDialSimpleNeedle.Arrow,
            True,
            Qt.QColor(Qt.Qt.red),
            Qt.QColor(Qt.Qt.gray).light(130)))

        self.setScaleOptions(Qwt.QwtDial.ScaleTicks | Qwt.QwtDial.ScaleLabel)
        self.setScaleTicks(0, 4, 8)

    # __init__()
    
    def setLabel(self, text):
        self.__label = text
        self.update()

    # setLabel()
    
    def label(self):
        return self.__label

    # label()
    
    def drawScaleContents(self, painter, center, radius):
        rect = Qt.QRect(0, 0, 2 * radius, 2 * radius - 10)
        rect.moveCenter(center)
        painter.setPen(self.palette().color(Qt.QPalette.Text))
        painter.drawText(
            rect, Qt.Qt.AlignBottom | Qt.Qt.AlignHCenter, self.__label)

    # drawScaleContents

# class SpeedoMeter


class AttitudeIndicatorNeedle(Qwt.QwtDialNeedle):

    def __init__(self, color):
        Qwt.QwtDialNeedle.__init__(self)
        palette = Qt.QPalette()
        for colourGroup in colorGroupList:
            palette.setColor(colourGroup, Qt.QPalette.Text, color)
        self.setPalette(palette)

    # __init__()
    
    def draw(self, painter, center, length, direction, cg):
        direction *= math.pi / 180.0
        triangleSize = int(round(length * 0.1))

        painter.save()

        p0 = Qt.QPoint(center.x() + 1, center.y() + 1)
        p1 = Qwt.qwtPolar2Pos(p0, length - 2 * triangleSize - 2, direction)

        pa = Qt.QPolygon([
            Qwt.qwtPolar2Pos(p1, 2 * triangleSize, direction),
            Qwt.qwtPolar2Pos(p1, triangleSize, direction + math.pi/2),
            Qwt.qwtPolar2Pos(p1, triangleSize, direction - math.pi/2),
            ])

        color = self.palette().color(cg, Qt.QPalette.Text)
        painter.setBrush(color)
        painter.drawPolygon(pa)

        painter.setPen(Qt.QPen(color, 3))
        painter.drawLine(
            Qwt.qwtPolar2Pos(p0, length - 2, direction + math.pi/2),
            Qwt.qwtPolar2Pos(p0, length - 2, direction - math.pi/2))

        painter.restore()

    # draw()

# class AttitudeIndicatorNeedle


class AttitudeIndicator(Qwt.QwtDial):

    def __init__(self, *args):
        Qwt.QwtDial.__init__(self, *args)
        self.__gradient = 0.0
        self.setMode(Qwt.QwtDial.RotateScale)
        self.setWrapping(True)
        self.setOrigin(270.0)
        self.setScaleOptions(Qwt.QwtDial.ScaleTicks)
        self.setScale(0, 0, 30.0)
        self.setNeedle(AttitudeIndicatorNeedle(
            self.palette().color(Qt.QPalette.Text)))

    # __init__()

    def angle(self):
        return self.value()

    # angle()
    
    def setAngle(self, angle):
        self.setValue(angle)

    # setAngle()

    def gradient(self):
        return self.__gradient

    # gradient()

    def setGradient(self, gradient):
        self.__gradient = gradient

    # setGradient()
    
    def keyPressEvent(self, event):
        if event.key() == Qt.Qt.Key_Plus:
            self.setGradient(self.gradient() + 0.05)
        elif event.key() == Qt.Qt.Key_Minus:
            self.setGradient(self.gradient() - 0.05)
        else:
            Qwt.QwtDial.keyPressEvent(self, event)

    # keyPressEvent()

    def drawScale(self, painter, center, radius, origin, minArc, maxArc):
        dir = (360.0 - origin) * math.pi / 180.0
        offset = 4
        p0 = Qwt.qwtPolar2Pos(center, offset, dir + math.pi)

        w = self.contentsRect().width()

        # clip region to swallow 180 - 360 degrees
        pa = []
        pa.append(Qwt.qwtPolar2Pos(p0, w, dir - math.pi/2))
        pa.append(Qwt.qwtPolar2Pos(pa[-1], 2 * w, dir + math.pi/2))
        pa.append(Qwt.qwtPolar2Pos(pa[-1], w, dir))
        pa.append(Qwt.qwtPolar2Pos(pa[-1], 2 * w, dir - math.pi/2))

        painter.save()
        painter.setClipRegion(Qt.QRegion(Qt.QPolygon(pa)))
        Qwt.QwtDial.drawScale(
            self, painter, center, radius, origin, minArc, maxArc)
        painter.restore()

    # drawScale()
    
    def drawScaleContents(self, painter, center, radius):
        dir = 360 - int(round(self.origin() - self.value()))
        arc = 90 + int(round(self.gradient() * 90))
        skyColor = Qt.QColor(38, 151, 221)
        painter.save()
        painter.setBrush(skyColor)
        painter.drawChord(
            self.scaleContentsRect(), (dir - arc)*16, 2*arc*16)
        painter.restore()

    # drawScaleContents()

# class AttitudeIndicator


class CockpitGrid(Qt.QFrame):
    
    def __init__(self, *args):
        Qt.QFrame.__init__(self, *args)

        self.setPalette(
            self.__colorTheme(Qt.QColor(Qt.Qt.darkGray).dark(150)))

        layout = Qt.QGridLayout(self)
        
        for i in xrange(3):
            layout.addWidget(self.__createDial(i), 0, i)

        for i in xrange(layout.columnCount()):
            layout.setColumnStretch(i, 1)

        self.__speed_offset = 0.8
        self.__angle_offset = 0.05
        self.__gradient_offset = 0.005
            
    # __init__()
    
    def __colorTheme(self, base):
        background = base.dark(150)
        foreground = base.dark(200)
        
        mid = base.dark(110)
        dark = base.dark(170)
        light = base.light(170)
        text = foreground.light(800)

        palette = Qt.QPalette()
        for colorGroup in colorGroupList:
            palette.setColor(colorGroup, Qt.QPalette.Base, base)
            palette.setColor(colorGroup, Qt.QPalette.Background, background)
            palette.setColor(colorGroup, Qt.QPalette.Mid, mid)
            palette.setColor(colorGroup, Qt.QPalette.Light, light)
            palette.setColor(colorGroup, Qt.QPalette.Dark, dark)
            palette.setColor(colorGroup, Qt.QPalette.Text, text)
            palette.setColor(colorGroup, Qt.QPalette.Foreground, foreground)
        
        return palette

    # __colorTheme()

    def __createDial(self, pos):
        dial = None
        if pos == 0:
            self.__clock = Qwt.QwtAnalogClock(self)
            knobColor = Qt.QColor(Qt.Qt.gray).light(130)
            for h in handList:
                handColor = Qt.QColor(Qt.Qt.gray).light(150)
                width = 8
                if h == Qwt.QwtAnalogClock.SecondHand:
                    handColor = Qt.Qt.gray
                    width = 5

                hand = Qwt.QwtDialSimpleNeedle(
                    Qwt.QwtDialSimpleNeedle.Arrow, True, handColor, knobColor)
                hand.setWidth(width)
                self.__clock.setHand(h, hand)
            timer = Qt.QTimer(self.__clock)
            timer.connect(timer,
                          Qt.SIGNAL('timeout()'),
                          self.__clock.setCurrentTime)
            timer.start(1000)
            dial = self.__clock
        elif pos == 1:
            self.__speedo = SpeedoMeter(self)
            self.__speedo.setRange(0.0, 240.0)
            self.__speedo.setScale(-1, 2, 20)
            timer = Qt.QTimer(self.__speedo)
            timer.connect(timer,
                          Qt.SIGNAL('timeout()'),
                          self.changeSpeed)
            timer.start(50)
            dial = self.__speedo
        elif pos == 2:
            self.__ai = AttitudeIndicator(self)
            gradientTimer = Qt.QTimer(self.__ai)
            gradientTimer.connect(gradientTimer,
                                  Qt.SIGNAL('timeout()'),
                                  self.changeGradient)
            gradientTimer.start(100)
            angleTimer = Qt.QTimer(self.__ai)
            angleTimer.connect(
                angleTimer, Qt.SIGNAL('timeout()'), self.changeAngle)
            angleTimer.start(100)
            dial = self.__ai

        if dial:
            dial.setReadOnly(True)
            dial.scaleDraw().setPenWidth(3)
            dial.setLineWidth(4)
            dial.setFrameShadow(Qwt.QwtDial.Sunken)

        return dial
    
    # __createDial()

    def changeSpeed(self):
        speed = self.__speedo.value()
        if ((speed < 40.0 and self.__speed_offset < 0.0)
            or (speed > 200.0 and self.__speed_offset > 0.0)):
            self.__speed_offset = -self.__speed_offset
        r = random.randrange(12)
        if r < 6:
            self.__speedo.setValue(speed + r*self.__speed_offset)

    # changeSpeed()

    def changeAngle(self):
        angle = self.__ai.angle()
        if angle > 180.0:
            angle -= 360.0

        if ((angle < -7.0 and self.__angle_offset < 0.0 )
            or (angle > 7.0 and self.__angle_offset > 0.0)):
            self.__angle_offset = -self.__angle_offset
            
        self.__ai.setAngle(angle + self.__angle_offset)

    # changeAngle()

    def changeGradient(self):
        gradient = self.__ai.gradient()

        if ((gradient < -0.05 and self.__gradient_offset < 0.0 )
            or (gradient > 0.05 and self.__gradient_offset > 0.0)):
            self.__gradient_offset = -self.__gradient_offset

        self.__ai.setGradient(gradient + self.__gradient_offset)

    # changeGradient()

# class CockpitGrid


def make():
    demo = Qt.QTabWidget()
    demo.addTab(CompassGrid(), "Compass")
    demo.addTab(CockpitGrid(), "Cockpit")
    demo.show()
    return demo

# make()


def main(args):
    app = Qt.QApplication(args)
    demo = make()
    sys.exit(app.exec_())

# main()


# Admire!
if __name__ == '__main__':
    if 'settracemask' in sys.argv:
        # for debugging, requires: python configure.py --trace ...
        import sip
        sip.settracemask(0x3f)

    main(sys.argv)
    
# Local Variables: ***
# mode: python ***
# End: ***