Modifications

Sauter à la navigation Sauter à la recherche
5 432 octets ajoutés ,  11 juillet 2016 à 10:17
aucun résumé de modification
Ligne 1 : Ligne 1 :  
{{RASP-PYGAME-GUI-NAV}}
 
{{RASP-PYGAME-GUI-NAV}}
 +
 +
{{traduction}}
 +
 +
== Introduction ==
 +
We're now going to improve the UI by introducing a widget framework [https://github.com/fictorial/pygameui PygameUI].
 +
 +
Update your version of distribute:
 +
 +
<syntaxhighlight lang="bash">
 +
sudo easy_install -U distribute
 +
</syntaxhighlight>
 +
 +
Install PygameUI:
 +
 +
<syntaxhighlight lang="bash">
 +
sudo pip install pygameui
 +
</syntaxhighlight>
 +
 +
PygameUI by default uses, IMO, a rather ugly font. If you want to change this you can simply copy a couple of True Type fonts into the pygameui resources directory.
 +
 +
You can find all the ttf files already on your Raspberry Pi with this command:
 +
 +
<syntaxhighlight lang="bash">
 +
sudo find / -type f  -name '*.ttf'
 +
</syntaxhighlight>
 +
 +
Now just copy a regular and a bold font over the existing ones in the resource directory. You may want to backup the originals just in case.
 +
 +
<syntaxhighlight lang="bash">
 +
cd /usr/local/lib/python2.7/dist-packages/pygameui/resources/fonts
 +
sudo mv bold.ttf bold.old
 +
sudo mv regular.ttf regular.old
 +
sudo cp /usr/share/fonts/truetype/freefont/FreeSans.ttf regular.ttf
 +
sudo cp /usr/share/fonts/truetype/freefont/FreeSansBold.ttf bold.ttf
 +
</syntaxhighlight>
 +
 +
This example controls GPIO #17 and #4 as before but now we're using the new framework.
 +
 +
{{ADFImage|RASP-PYGAME-GUI-PygameUI-GPIO-00.jpg}}
 +
 +
The widget rendering and touchscreen events are handled by PygameUI. The PiTft class defines the buttons to draw on screen and the click event to be fired when a button is pressed.
 +
 +
{{ADFImage|RASP-PYGAME-GUI-PygameUI-GPIO-01.png}}
 +
 +
== Démarrer ==
 +
At the top here we've now imported the pygameui library. We use it quite a bit later on so {{fname|ui}} is a nice short alias for it.
 +
 +
The other key addition here is {{https://docs.python.org/2/library/logging.html logging}}. When using more libraries and frameworks it's very useful to set up logging so you can see the output in a file or, in this case, on the console. We're also able to configure the logger into {{fname|DEBUG}} mode so we can really see what's going on underneath our code and troubleshoot if needs be.
 +
 +
<syntaxhighlight lang="python">
 +
import pygame
 +
import os
 +
import pygameui as ui
 +
import logging
 +
import RPi.GPIO as GPIO
 +
 +
#Setup the GPIOs as outputs - only 4 and 17 are available
 +
GPIO.setmode(GPIO.BCM)
 +
GPIO.setup(4, GPIO.OUT)
 +
GPIO.setup(17, GPIO.OUT)
 +
 +
log_format = '%(asctime)-6s: %(name)s - %(levelname)s - %(message)s'
 +
console_handler = logging.StreamHandler()
 +
console_handler.setFormatter(logging.Formatter(log_format))
 +
logger = logging.getLogger()
 +
logger.setLevel(logging.DEBUG)
 +
logger.addHandler(console_handler)
 +
 +
os.putenv('SDL_FBDEV', '/dev/fb1')
 +
os.putenv('SDL_MOUSEDRV', 'TSLIB')
 +
os.putenv('SDL_MOUSEDEV', '/dev/input/touchscreen')
 +
</syntaxhighlight>
 +
 +
== Définition de l'interface utilisateur ==
 +
For some hints on how to use widgets within the framework take a look at the [https://github.com/fictorial/pygameui/blob/master/bin/pygameui-kitchensink.py kitchen sink (pygameui-kitchensink.py)] script.
 +
 +
The basic principle is that you define a class that inherits from {{fname|ui.Scene}} and in the {{fname|__init__}} method you define all the widgets. A Scene is the full window, in our case the entire display (320,240).
 +
 +
Each button's position and size is defined using a {{fname|ui.Rect}} and a text label is also supplied. An {{fname|on_clicked}} handler is then assigned - this handler is called when the button is clicked. In our case this is the {{fname|gpi_button}} method.
 +
 +
The  {{fname|gpi_button}} method simply looks at the label of the button that's been clicked to determine which GPIO to set on or off.
 +
 +
<syntaxhighlight lang="python">
 +
MARGIN = 20
 +
 +
class PiTft(ui.Scene):
 +
    def __init__(self):
 +
        ui.Scene.__init__(self)
 +
 +
        self.on17_button = ui.Button(ui.Rect(MARGIN, MARGIN, 130, 90), '17 on')
 +
        self.on17_button.on_clicked.connect(self.gpi_button)
 +
        self.add_child(self.on17_button)
 +
 +
        self.on4_button = ui.Button(ui.Rect(170, MARGIN, 130, 90), '4 on')
 +
        self.on4_button.on_clicked.connect(self.gpi_button)
 +
        self.add_child(self.on4_button)
 +
 +
        self.off17_button = ui.Button(ui.Rect(MARGIN, 130, 130, 90), '17 off')
 +
        self.off17_button.on_clicked.connect(self.gpi_button)
 +
        self.add_child(self.off17_button)
 +
 +
        self.off4_button = ui.Button(ui.Rect(170, 130, 130, 90), '4 off')
 +
        self.off4_button.on_clicked.connect(self.gpi_button)
 +
        self.add_child(self.off4_button)
 +
 +
    def gpi_button(self, btn, mbtn):
 +
        logger.info(btn.text)
 +
       
 +
        if btn.text == '17 on':
 +
            GPIO.output(17, False)
 +
        elif btn.text == '4 on':
 +
            GPIO.output(4, False)
 +
        elif btn.text == '17 off':
 +
            GPIO.output(17, True)
 +
        elif btn.text == '4 off':
 +
            GPIO.output(4, True)
 +
 +
ui.init('Raspberry Pi UI', (320, 240))
 +
pygame.mouse.set_visible(False)
 +
ui.scene.push(PiTft())
 +
</syntaxhighlight>
 +
 +
== La boucle principale ==
 +
This is a key point. The main loop of you program is now taken care of by pygameui. The [https://en.wikipedia.org/wiki/Inversion_of_control control has been inverted] - we've supplied pygameui with code to call when certain user actions occur.
 +
 +
The pygameui main loop is started with this final line of code:
 +
 +
<syntaxhighlight lang="bash">
 +
ui.run()
 +
</syntaxhighlight>
 +
 +
As usual, you can run this from the pygamelcd project:
 +
 +
<syntaxhighlight lang="bash">
 +
sudo python test4.py
 +
</syntaxhighlight>
    
{{RASP-PYGAME-GUI-TRAILER}}
 
{{RASP-PYGAME-GUI-TRAILER}}
29 918

modifications

Menu de navigation