Forum >> Programmazione Python >> GUI >> Tkinter e ciclo while

Pagina: 1

Buongiorno
premetto che di programmazione mi intendo pochissimo, copiazzando un po in giro sono riuscito a fare un piccolo programma che ha un minimo di senso.
Si tratta di un robottino pilotato da raspberry che funziona con un interfaccia grafica fatta con tkinter.
Sono bloccato su un ciclo while che non so come interrompere premendo il pulsante stop.
allego il programma:

try: import Tkinter as tk # verifico se il modulo tk è aperto con Py2
except ImportError: import tkinter as tk # altrimenti lo apro con Py3

import RPi.GPIO as GPIO #impoto la libreria gpio e la chiamo GPIO

import time # Importo la libreria time

GPIO.setmode (GPIO.BCM) #uso il metodo in/out BCM

GPIO.setwarnings(False) #disabilito i messaggi di errore sulla gpio

GPIO.setup(17,GPIO.OUT,initial=GPIO.LOW) # imposto gpio 17 come uscita e spento
GPIO.setup(27,GPIO.OUT,initial=GPIO.LOW) # imposto gpio 27 come uscita e spento
GPIO.setup(22,GPIO.OUT,initial=GPIO.LOW) # imposto gpio 22 come uscita e spento
GPIO.setup(18,GPIO.OUT,initial=GPIO.LOW) # imposto gpio 18 come uscita e spento

def mdavanti(): #definizione motore destra avanti
GPIO.output(17,False)
GPIO.output(27,False)
GPIO.output(18,False)
GPIO.output(22,False)
GPIO.output(17,False)
GPIO.output(27,True)
time.sleep(1)

def mdindietro(): #definizione motore destra indietro
GPIO.output(17,False)
GPIO.output(27,False)
GPIO.output(18,False)
GPIO.output(22,False)
GPIO.output(17,True)
GPIO.output(27,False)
time.sleep(1)

def msavanti(): #definizione motore sinistra avanti
GPIO.output(17,False)
GPIO.output(27,False)
GPIO.output(18,False)
GPIO.output(22,False)
GPIO.output(18,False)
GPIO.output(22,True)
time.sleep(1)

def msindietro(): #definizione motore sinistra indietro
GPIO.output(17,False)
GPIO.output(27,False)
GPIO.output(18,False)
GPIO.output(22,False)
GPIO.output(18,True)
GPIO.output(22,False)
time.sleep(1)

def stop(): #definizione robot stop
GPIO.output(17,False)
GPIO.output(27,False)
GPIO.output(18,False)
GPIO.output(22,False)

def robotavanti():#definizione robot avanti
GPIO.output(17,False)
GPIO.output(27,False)
GPIO.output(18,False)
GPIO.output(22,False)
GPIO.output(17,False)
GPIO.output(27,True)
GPIO.output(18,False)
GPIO.output(22,True)
time.sleep(1)


def robotindietro(): #definizione robot avanti
GPIO.output(17,False)
GPIO.output(27,False)
GPIO.output(18,False)
GPIO.output(22,False)
GPIO.output(17,True)
GPIO.output(27,False)
GPIO.output(18,True)
GPIO.output(22,False)
time.sleep(1)

def automatico(): ################################ come faccio premendo il tasto stop a fermare questo ?????
while 1:
robotindietro()
time.sleep(4)
robotavanti()
time.sleep( 8)
msavanti()
time.sleep(5)
robotavanti()
time.sleep(2)
mdindietro()
time.sleep(2)


class Applicazione: # CREO INTERFACCIA GRAFICA

def __init__ (self):

self.form1 = tk.Tk() # creo la finestra principale
self.form1.title("Frangesco Il Grosso") # titolo della finestra principale
self.form1.resizable(False, False) # imposto la finestra non ridimensionabile
self.form1.geometry("%dx%d+%d+%d" % (680,400,200,200))# imposto la posizione fissa della finestra
# e le dimensioni
self.frame1 = tk.Frame(self.form1) # creo il contenitore 1 nella finestra principale
self.frame2 = tk.Frame(self.form1) # creo il contenitore 2 nella finestra principale
self.frame3 = tk.Frame(self.form1) # creo il contenitore 3 nella finestra principale
self.frame4 = tk.Frame(self.form1) # creo il contenitore 4 nella finestra principale



self.avanti = tk.Button(self.frame1, text="AVANTI", command = robotavanti) # creo il pulsante avanti
self.indietro = tk.Button(self.frame1, text="INDIETRO", command = robotindietro) # creo il pulsante indietro
self.destra = tk.Button(self.frame1, text="DESTRA", command = mdavanti) # creo il pulsante destra
self.sinistra = tk.Button(self.frame1, text="SINISTRA", command = msavanti) # creo il pulsante sinistra
self.stop = tk.Button(self.frame1, text="STOP", command = stop) # creo il pulsante stop

self.auto = tk.Button(self.frame2, text="AUTO", command = automatico) #, command = automatico) # creo il pulsante automatico



self.frame1.configure(bg="yellow", width=350, height=200) # colore finestra 1
self.frame2.configure(bg="red", width=350, height=200) # colore finestra 2
self.frame3.configure(bg="blue", width=350, height=200) # colore finestra 3
self.frame4.configure(bg="green", width=350, height=200) # colore finestra 4

self.frame1.grid(row=0, column=0) #piazzo la finestra 1 sulla griglia
self.frame2.grid(row=0, column=1) #piazzo la finestra 2 sulla griglia
self.frame3.grid(row=1, column=0) #piazzo la finestra 3 sulla griglia
self.frame4.grid(row=1, column=1) #piazzo la finestra 4 sulla griglia

self.avanti.grid(row=0, column=3) #piazzo il pulsante avanti sulla griglia della finestra 1
self.destra.grid(row=2, column=5) #piazzo il pulsante sinistra sulla griglia della finestra 1
self.sinistra.grid(row=2, column=0) #piazzo il pulsante sinistra sulla griglia della finestra 1
self.indietro.grid(row=3, column=3) #piazzo il pulsante sinistra sulla griglia della finestra 1
self.stop.grid(row=5, column=3 ) #piazzo il pulsante indietro sulla griglia della finestra 2

self.auto.grid(row=0, column=3) #piazzo il pulsante automatico sulla griglia della finestra 2

def start(self):
self.form1.mainloop() # lancio il programma
GPIO.cleanup()

app = Applicazione()
app.start()
Ringrazio tutti coloro che vorranno aiutarmi e sopratutto consigliarmi qualcosa di veramente basilare per capire il funzionamento di python e tkinter.


--- Ultima modifica di ubepp in data 2017-05-09 16:25:46 ---
Salve a tutti,
sono alle primissime armi anche io con l'apprendimento di Python(3), e non mi è chiaro il funzionamento con Tkinter ed i cicli while , mi sembra di capire che strutturando così il programma rimane nel ciclo di while e la finestra principale non si aggiorna.

Ho il tuo stesso scoglio e non capisco come uscire da un ciclo while in seguito alla pressione di un bottone della finestra principale.

Ho provato ad inserire nel ciclo anche un refresh della schermata con canvas.update_idletasks() , come la creazione del pulsante per interrompere all'interno del ciclo di while, ma senza risultati.

Scusate la mia ignoranza in materia me se avete una spiegazione mi farebbe comodo.

Grazie



Consiglio di dare un occhiata qui per quel che riguarda il while:


http://www.python.it/doc/Howtothink/Howtothink-html-it/chap06.htm

Secondo voi si potrebbe risolvere questo specifico problema utilizzando il metodo AFTER in sostituzione al ciclo WHILE ?


--- Ultima modifica di Sertergi in data 2017-05-18 11:13:32 ---
Nel mio programma sono riuscito a risolvere sostituendo il ciclo while di Python, con il ciclo after di tk, e inserendo una variabile globale.
L'esempio seguente è scritto con Python 3.4.2 , mi scuso in anticipo per la mia scrittura basilare con l'utilizzo di variabili globali, ma sono agli inizi :fingers-crossed: ( sto cercando di capire ancora bene la programmazioni a classi )



Nell'esempio nel ciclo start stampa data e ora come output nella shell di Python




# importa tutti i moduli Tkinter
import tkinter
from tkinter import *

# importa i moduli data e ora
import datetime

# definisci variabile globale startvar
global startvar
startvar = True

# definisci start
def start():
    global jobstart
    if startvar == True:
        startbutton = Button (text="START", bg="dark green", command=start, state="disabled").grid(row=1, column=0)
        stopbutton = Button (text="STOP/EXIT", bg="red2", command=stop).grid(row=2, column=0)
        dataeora = ("%s" % datetime.datetime.now().isoformat())
        print ("Data e ora : ", dataeora)
        # inserire eventuali altre funzioni nel ciclo di start qui
        finestra.update_idletasks()
        jobstart = finestra.after(1000, start)

# definisci stop
def stop():
    global jobstart
    finestra.after_cancel(jobstart)
    startbutton = Button (text="START", bg="dark green", command=start, state="normal").grid(row=1, column=0)
    print ("hai premuto stop")
    uscita = messagebox.askyesno(title="USCITA", message="Vuoi davvero Uscire?")
    if uscita :
        finestra.destroy()
    
# crea la finestra principale
finestra = Tk ()
finestra.geometry ('400x240+0+0')
finestra.title ('Exit loop Tk')
startbutton = Button (text="START", bg="dark green", command=start).grid(row=1, column=0)

# mainloop finestra
finestra.update_idletasks()
finestra.mainloop()








--- Ultima modifica di Sertergi in data 2017-05-29 20:05:52 ---


Pagina: 1



Esegui il login per scrivere una risposta.