Buttons deaktivieren, bis die Aktion zu Ende geführt wird.

Fragen zu Tkinter.
Antworten
access2382
User
Beiträge: 1
Registriert: Montag 20. Oktober 2014, 01:08

hallo Leute,

ich bin ein Python-Neuling und habe letzte Woche angefangen mich damit zu beschäftigen und mit meinem Raspberry Pi ein "Licht-Mischer" zu bauen. Man soll über ein Touchscreen-Display verschiedene Programme ausführen können. Nach dem man ein Programm ausgewählt hat, sollen verschiedene LEDs, verschieden lang leuchten (im Code habe ich noch nicht die endgültigen Zeiten drin) und nach einer bestimmten Zeit ausgehen (wundert euch die vertauschten "True" und "False" nicht, da die Relaiskarte, woran die LEDs angeschlossen sind, es zum Schalten so erfordert).

Soweit klappt alles auch. Wenn ich auf ein Button klicke ändert dieses seine Farbe bis das Programm zu Ende gelaufen ist. Jetzt kommt mein Problem:

Wenn ich während das Programm abläuft auf die anderen Buttons draufdrücke, dann werden die jewiligen Programme im Anschluss sofort ausgeführt. Ich hätte aber gerne, dass während ein Programm abläuft, alle Buttons gesperrt sind. Jedoch kriege ich seit zwei Tagen das Ganze nicht hin. Habt ihr vllt. eine Lösung für mich??? Danke im Voraus für die Mühen!!!

Code: Alles auswählen

# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO
import time
from Tkinter import *

GPIO.setmode(GPIO.BCM)

led-eins = 0
led-zwei = 1
led-drei = 2
led-vier = 3
led-fünf = 4
led-sechs = 5
led-sieben = 6
led-acht = 7

Lichtmischer = [4,17,18,21,22,23,24,25]

GPIO.setup(Lichtmischer[led-eins], GPIO.OUT, initial=True)
GPIO.setup(Lichtmischer[led-zwei], GPIO.OUT, initial=True)
GPIO.setup(Lichtmischer[led-drei], GPIO.OUT, initial=True)
GPIO.setup(Lichtmischer[led-vier], GPIO.OUT, initial=True)
GPIO.setup(Lichtmischer[led-fünf], GPIO.OUT, initial=True)
GPIO.setup(Lichtmischer[led-sechs], GPIO.OUT, initial=True)
GPIO.setup(Lichtmischer[led-sieben], GPIO.OUT, initial=True)
GPIO.setup(Lichtmischer[led-acht], GPIO.OUT, initial=True)

root = Tk()
root.geometry('1024x600')
#root.configure(bg='white')
root.title("COCKTAIL-Lichtmischer")

def light1():
        time.sleep(2)
        GPIO.output(Lichtmischer[led-eins],False)
        time.sleep(3)
        GPIO.output(Lichtmischer[led-eins],True)
        time.sleep(2)

def light2():
        time.sleep(2)
        GPIO.output(Lichtmischer[led-zwei],False)
        time.sleep(3)
        GPIO.output(Lichtmischer[led-zwei],True)
        time.sleep(2)
                
def light3():
        time.sleep(2)
        GPIO.output(Lichtmischer[led-drei],False)
        time.sleep(3)
        GPIO.output(Lichtmischer[led-drei],True)
        time.sleep(2)
                       
def light4():
        time.sleep(2)
        GPIO.output(Lichtmischer[led-vier],False)
        time.sleep(3)
        GPIO.output(Lichtmischer[led-vier],True)
        time.sleep(2)
                
def light5():
        time.sleep(2)
        GPIO.output(Lichtmischer[led-fünf],False)
        time.sleep(3)
        GPIO.output(Lichtmischer[led-fünf],True)
        time.sleep(2)
                
def light6():
        time.sleep(2)
        GPIO.output(Lichtmischer[led-sechs],False)
        time.sleep(3)
        GPIO.output(Lichtmischer[led-sechs],True)
        time.sleep(2)
               
def light7():
        time.sleep(2)
        GPIO.output(Lichtmischer[led-sieben],False)
        time.sleep(3)
        GPIO.output(Lichtmischer[led-sieben],True)
        time.sleep(2)
                        
def light8():
        time.sleep(2)
        GPIO.output(Lichtmischer[led-acht],False)
        time.sleep(3)
        GPIO.output(Lichtmischer[led-acht],True)
        time.sleep(2)
                
Label(root,
      text="Licht Show", font=('sans-serif', 25, 'bold')).grid(row=0, column=0)

Label(root,
      text="Bitte Programm auswählen.   ", font=('sans-serif', 20, 'italic')).grid(row=0, column=1, sticky=E)

Label(root,
      text="", font=('sans-serif', 25,)).grid(row=1, column=1)

Button(root,
       text="Programm 1", width=21, height=3, font=('sans-serif', 25, 'bold'),
       command=light1).grid(row=2, column=0)

Button(root,
       text="Programm 2", width=21, height=3, font=('sans-serif', 25, 'bold'),
       command=light2).grid(row=3, column=0)

Button(root,
       text="Programm 3", width=21, height=3, font=('sans-serif', 25, 'bold'),
       command=light3).grid(row=4, column=0)

Button(root,
       text="Programm 4", width=21, height=3, font=('sans-serif', 25, 'bold'),
       command=light4).grid(row=5, column=0)

Button(root,
       text="Programm 5", width=22, height=3, font=('sans-serif', 25, 'bold'),
       command=light5).grid(row=2, column=1)

Button(root,
       text="Programm 6", width=22, height=3, font=('sans-serif', 25, 'bold'),
       command=light6).grid(row=3, column=1)

Button(root,
       text="Programm 7", width=22, height=3, font=('sans-serif', 25, 'bold'),
       command=light7).grid(row=4, column=1)

Button(root,
       text="Programm 8", width=22, height=3, font=('sans-serif', 25, 'bold'),
       command=light8).grid(row=5, column=1)

root.mainloop()
GPIO.cleanup()
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@access2382: dass soweit alles klappt bezweifle ich mal. In Zeile 8 ist schon der erste Syntaxerror, weil man einem Operator nichts zuweisen kann. Du solltest auch dringend lernen, was Schleifen sind und tun. Um Buttons aus und anschalten zu können, mußt Du Dir die Referenz auf den jeweiligen Knopf merken, dazu brauchst Du sinnvollerweise Kenntnisse in Objektorientierter Programmierung. Dann wird das Ganze immer noch nicht tun, weil Du mit jedem Knopfdruck Deine GUI einfrierst und Mausereignisse erst wieder danach verarbeitet werden, das heißt, wenn die Knöpfe schon wieder aktiviert wären. Das Problem ließe sich dann, oder schon jetzt, mit 'after' lösen.

PS: Sternchenimporte sind böse und alles sollte in Funktionen gepackt werden; wenn Du sowieso alles neu schreiben mußt, kannst Du diese beiden Punkte auch gleich beheben.
BlackJack

@access2382: Ergänzend dazu: Konvention für die Einrücktiefe ist vier Leerzeichen pro Ebene. Ein Blick in den Style Guide for Python Code könnte sich lohnen.

Konstantennamen werden durchgehend in Grossbuchstaben geschrieben.

In Python 2 sind keine Umlaute in Namen erlaubt.

Bei den `led-*`-Konstanten erscheinen mir die Werte überflüssig. Da würde man direkt die PIN-Nummern als Werte erwarten.

Neben Schleifen wären auch Funktionen interessant. Also ”echte” Funktionen und nicht einfach nur einem Stück Code einen Namen geben um den anspringen zu können. Statt für jedes Licht nahezu das selbe zu schreiben hätte es hier auch *eine* Funktion getan der man die LED als Argument übergibt.

Edit: Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf8
import Tkinter as tk
from functools import partial

from RPi import GPIO


LED_PINS = [4, 17, 18, 21, 22, 23, 24, 25]


def run_program(button, pin):
    button['state'] = tk.DISABLED
    yield 2
    GPIO.output(pin, False)
    yield 3
    GPIO.output(pin, True)
    yield 2
    button['state'] = tk.NORMAL


class ProgramsUI(tk.Frame):
    def __init__(self, master, pins, buttons_per_row=4):
        tk.Frame.__init__(self, master)
        for i, pin in enumerate(pins):
            row, column = divmod(i, buttons_per_row)
            button = tk.Button(self, text='Programm {0}'.format(i))
            button['command'] = partial(self.do_program, button, pin)
            button.grid(row=row, column=column)

    def _do_steps(self, steps):
        try:
            seconds = next(steps)
        except StopIteration:
            return
        else:
            self.after(seconds * 1000, self._do_steps, (steps,))

    def do_program(self, button, pin):
        self._do_steps(run_program(button, pin))


def main():
    GPIO.setmode(GPIO.BCM)
    try:
        for pin in LED_PINS:
            GPIO.setup(pin, GPIO.OUT, initial=True)

        root = tk.Tk()
        root.title('COCKTAIL-Lichtmischer')

        programs_ui = ProgramsUI(root, LED_PINS)
        programs_ui.pack()

        root.mainloop()
    finally:
        GPIO.cleanup()
Antworten