Ligne 85 : |
Ligne 85 : |
| | | |
| == Le thread du potentiomètre == | | == Le thread du potentiomètre == |
− | xxx
| + | A thread is used to constantly read the potentiometer. If you take the reading in-line in the scene update method then you'll slow down the screen refresh rate. This separate thread allows the screen to be redrawn in parallel with us reading a value from the ADC. |
| + | |
| + | The class is defined as a callable - hence the {{đname|__call__}} method. It takes a reference to the pitft class so we can update values on it. There's a simple termination scheme used by checking a flag on every loop. Later on you'll see how we cleanly close the program by setting this flag. |
| + | |
| + | So we simply read the voltage value from the ADC and set the label and progress bar position on the pitft. |
| + | |
| + | <syntaxhighlight lang="python"> |
| + | class PotReader(): |
| + | def __init__(self, pitft): |
| + | self.pitft = pitft |
| + | self.terminated = False |
| + | |
| + | def terminate(self): |
| + | self.terminated = True |
| + | |
| + | def __call__(self): |
| + | while not self.terminated: |
| + | # Read channel 0 in single-ended mode using the settings above |
| + | volts = adc.readADCSingleEnded(0, gain, sps) / 1000 |
| + | self.pitft.set_volts_label(volts) |
| + | self.pitft.set_progress(volts / 3.3) |
| + | </syntaxhighlight> |
| + | |
| + | |
| + | == Définition de l'interface utilisateur == |
| + | We've added a couple more widgets to the scene now and resized the buttons to accommodate them. We're showing the voltage on a label and a progress widget. The {{fname|set_progress}} and {{fname|set_volts_label}} methods are called from the PotReader thread to update the values in these widgets. |
| + | |
| + | <syntaxhighlight lang="python"> |
| + | class PiTft(ui.Scene): |
| + | def __init__(self): |
| + | ui.Scene.__init__(self) |
| + | |
| + | self.on17_button = ui.Button(ui.Rect(MARGIN, MARGIN, 130, 60), '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, 60), '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, 100, 130, 60), '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, 100, 130, 60), '4 off') |
| + | self.off4_button.on_clicked.connect(self.gpi_button) |
| + | self.add_child(self.off4_button) |
| + | |
| + | self.progress_view = ui.ProgressView(ui.Rect(MARGIN, 200, 280, 40)) |
| + | self.add_child(self.progress_view) |
| + | |
| + | self.volts_value = ui.Label(ui.Rect(135, 170, 50, 30), '') |
| + | self.add_child(self.volts_value) |
| + | |
| + | 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) |
| + | |
| + | def set_progress(self, percent): |
| + | self.progress_view.progress = percent |
| + | |
| + | def set_volts_label(self, volts): |
| + | self.volts_value.text = '%.2f' % volts |
| + | |
| + | def update(self, dt): |
| + | ui.Scene.update(self, dt) |
| + | </syntaxhighlight> |
| + | |
| + | == Et pour finir... == |
| + | To start everything going we initialise pygameui, construct the pitft class and then start the potreader thread with a reference to pitft. |
| + | |
| + | Since we're running this extra thread we need a clean way to stop the program. A signal handler is used to trap ctrl+c and terminate the PotReader thread before calling sys.exit - otherwise the program will not close. |
| + | |
| + | <syntaxhighlight lang="python"> |
| + | ui.init('Raspberry Pi UI', (320, 240)) |
| + | pygame.mouse.set_visible(False) |
| + | |
| + | pitft = PiTft() |
| + | |
| + | # Start the thread running the callable |
| + | potreader = PotReader(pitft) |
| + | threading.Thread(target=potreader).start() |
| + | |
| + | def signal_handler(signal, frame): |
| + | print 'You pressed Ctrl+C!' |
| + | potreader.terminate() |
| + | sys.exit(0) |
| + | |
| + | signal.signal(signal.SIGINT, signal_handler) |
| + | |
| + | ui.scene.push(pitft) |
| + | ui.run() |
| + | </syntaxhighlight> |
| + | |
| + | You can run this final example from the pygamelcd project: |
| + | |
| + | <syntaxhighlight lang="bash"> |
| + | sudo python test5.py |
| + | </syntaxhighlight> |
| + | |
| | | |
| | | |
| {{RASP-PYGAME-GUI-TRAILER}} | | {{RASP-PYGAME-GUI-TRAILER}} |