Seite 1 von 1

While Schleife beenden

Verfasst: Sonntag 15. März 2015, 11:27
von KuniBert
Hallo,
ich sitze jetzt schon mehrere Tage an dem Problem wie ich eine While Endlosschleife mit ESC oder ENTER beenden kann ohne dass das komplette Programm beendet wird oder die Endlosschleife zwischendurch auf eine USER Eingabe wartet.
Mein Programm sieht so aus.

Code: Alles auswählen

import dialog
import time
import sys, os , select
import subprocess
import time
import picamera
from fractions import Fraction
from PIL import Image
from pytesser import *
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
GPIO.setup(23, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
GPIO.setup(17, GPIO.OUT)
GPIO.setup(22, GPIO.OUT)
GPIO.cleanup()
# Dialogbox initialisieren
d = dialog.Dialog(dialog="dialog")
# Menubox erzeugen
while 1:
  (code, tag) = d.menu(
    "Programmwahl",
    width=80,
    choices=[("Programm", "Schrankenautomatik"),
             ("Kennzeichen", "hier koennen sie Kennzeichen eingeben"),
             ("Ende", "Programm Ende")])
         
  if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
    break
  if code == d.DIALOG_OK:
    GPIO.setup(22, GPIO.OUT)
    GPIO.output(22, 0)
    d.infobox("Ihre Auswahl: " + tag)
    time.sleep(1)

    
    
    while tag == 'Programm':
       kenndaten = open("KennzeichenDaten.txt" , "r")
       kenndb = kenndaten.read()
       kenndaten.close()
       d.infobox("mit Taster gehts los")
       GPIO.setup(23, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
       GPIO.wait_for_edge(23, GPIO.RISING)
       GPIO.output(22,1)
       GPIO.setup(17, GPIO.OUT)
       GPIO.output(17,0)
       d.infobox("Programm läuft!")
       
       with picamera.PiCamera() as camera:	  
          camera.resolution = (750, 400)
          camera.shutter_speed = 6000000
          camera.expusure_mode = 'off'
          camera.iso = 800
          camera.start_preview()# Camera warm-up time
          time.sleep(2)
          camera.capture('Test.jpg')
          camera.close()##Zeit fuer Imagemagick 
          time.sleep(2)    ## image umwandlung in Grau und anpassung
          returncode = subprocess.call(['convert', 'Test.jpg', '-colorspace', 'gray','-auto-gamma','-brightness-contrast', '+15x+45', '-sharpen','4', '-compress', 'none', 'Test3.tif'])##Zeit fuer Tesseract OCR
          time.sleep(3)  ## teerat start
          image_file = 'Test3.tif'
          im = Image.open(image_file)
          ocr = image_to_string(im)
          a = ocr.strip()
          b = kenndb.strip()
          GPIO.output(17, 1)
          if a is '':
			  d.infobox("Kein Kennzeichen fotografiert!")
			  time.sleep(4)
			  GPIO.output(22,0)
			  GPIO.output(17,1)
			  continue

          elif a in b:
			  d.infobox("Kennzeichen gefunden")
			  time.sleep(4)
			  continue
          else:
			  d.infobox("Kennzeichen nicht gefunden")
			  time.sleep(4)
			  continue
			



# Programm ohne Fehler beenden
sys.exit(0)
Es ist an einigen Stellen sicher nicht korrekt Programmiert, es funktioniert jedoch. Ich hoffe ihr habt da eine Idee.
Wie gesagt die zweite while Schleife soll Endlos laufen bis eine Eingabe gemacht wird und dann das Hauptmenü wieder aufgerufen wird.
Achso das ganze läuft auf einem RPi mit python 2.

Re: While Schleife beenden

Verfasst: Sonntag 15. März 2015, 12:52
von BlackJack
@KuniBert: Ich denke die einfachste Möglichkeit dürfte Strg+C sein was eine `KeyboardInterrupt`-Ausnahme auslöst und die kann man dann entsprechend abfangen.

Das Programm enthält einen Fehler: ``a is ''`` garantiert nicht das diese Bedingung wahr ist wenn `a` eine leere Zeichenkette ist, denn es ist nicht garantiert das es in einem Programm die leere Zeichenkette tatsächlich nur *einmal* als Objekt gibt. Es könnte auch verschiedene Objekte geben. ``is`` sollte man wirklich nur verwenden wenn man sich 100% *sicher* ist das man keine Werte sondern Objektidentitäten vergleichen möchte. Dass das scheinbar in dem Programm funktioniert ist Zufall.

Re: While Schleife beenden

Verfasst: Sonntag 15. März 2015, 12:55
von jerch
@KuniBert:
Bitte bitte nutze strukturierte Programmierung, Funktionen sind sehr gut geeignet dafür. Sowas hier möchte keiner lesen und debuggen (fehlt eigentlich nur noch das GOTO ;) ).

Zu Deinem Problem:
Damit das funktioniert, musst Du die Tastatureingabe abfangen und in der Subschleife auswerten. Da die Eingabe optional ist, sollte die Tastaturabfrage nicht blockieren. Das geht u.a. hiermit:

Code: Alles auswählen

import sys
import os
import termios
from tty import setcbreak
from select import select
from contextlib import contextmanager

READ_TIMEOUT = .1

@contextmanager
def cbreak_terminal(file_obj=sys.stdin):
    fd = file_obj.fileno()
    try:
        old_attr = termios.tcgetattr(fd)
        setcbreak(fd)
        yield file_obj
    finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, old_attr)

def read_keys(file_obj=sys.stdin):
    fd = file_obj.fileno()
    if select([fd], [], [], READ_TIMEOUT)[0]:
        return os.read(fd, 1024)
    return ''

if __name__ == '__main__':
    with cbreak_terminal():
        while True:
            print repr(read_keys())