Forum >> Programmazione Python >> GUI >> Prendere il controllo da fuori interfaccia Tkainter

Pagina: 1

Buongiorno a tutti , quest’oggi ho un quesito di questo tipo.
Ho notato che quando io utilizzo in un programma l’interfaccia Tkinter ci sono dei problemini.
Se creo una interfaccia che visualizza delle label e dei button questa gira sempre su se stessa.
Intendo dire che se io con un pulsante avvio una funzione contatore e voglio che il conteggio venga visualizzato (in continuazione) da un label nell’interfaccia creata da Tkinter questo avviene solo quando Tkinter lascia il controllo.
Ora avrei la necessità di cambiare il colore di un button quando io , tramite opportuna interfaccia, porto a livello logico 1 un certo Pin del Gpio.
Come posso fare perché Tkinter “molli l’osso” e mi lasci passare il cambio di stato.
Scusandomi se non sono stato chiaro, ringrazio chi vorrà aiutarmi.
Grazie

Alberto :question:
------
Alberto
domanda: ma il conteggio fa parte di un loop?
da quello che mi è parso di capire, finito il loop di conteggio, allora lo script va avanti e vede i cambiamenti di altre variabili.

ma allora non si può inserire il refresh di quelle variabili dentro il menù di conteggio in modo che ad ogni secondo se ne visualizzi lo stato?
domanda: ma il conteggio fa parte di un loop?
da quello che mi è parso di capire, finito il loop di conteggio, allora lo script va avanti e vede i cambiamenti di altre variabili.

ma allora non si può inserire il refresh di quelle variabili dentro il menù di conteggio in modo che ad ogni secondo se ne visualizzi lo stato?

Il problema è che se anche tu aggiorni le variabili lui non le considera finchè tkainter non perde il controllo.
La cosa è ancora piu' problematica se la richiesta di aggiornamento arriva da una periferica che "dovrebbe" riusciere a interrompere momentaneamente il MONOPOLIO dell'interfaccia grafica e farmi aggiornare il colore del pulsante.
La mia ricerca è nel comando da utilizzare per questo.
Intanto Grazie.... se hai idee da suggerire non esitare,,,,
------
Alberto
prova a vedere se questo fa a caso tuo, l'ho trovato su stackoverflow
https://stackoverflow.com/questions/8121592/how-do-i-change-dynamically-the-text-of-a-button-in-tkinter





qui il codice completo




from tkinter import*
import tkinter as tk
import os


def change_button_text(name, index, mode):
buttontext.set(widget1.get())

app=Tk()
app.title("Example")
app.geometry('200x200+200+200')

widget1 = StringVar()
widget1.set('Numbers')
files =["one",'two','three']
widget1DropDown = OptionMenu(app, widget1, *files)
widget1DropDown.config(bg = 'white',foreground='black',font=("Times",16,"italic"))
widget1DropDown["menu"].config(bg = 'white',font=("Times",12,"italic"))
widget1DropDown.pack()
widget1.trace("w", change_button_text)


buttontext=StringVar()
buttontext.set('Zero')
button1=Button(app,textvariable=buttontext,font=("Times", 16),width=15,borderwidth=5)
button1.pack(side=LEFT, padx=5,pady=8)


app.mainloop()




questo codice riesce a cambiare in maniera dinamica il testo di un bottone cambiandolo da un menù a tendina, ora facendo le debite proporzioni (l'input qui è manuale, il tuo arriva dal raspy, qui cambia il testo di un bottone, tu devi cambiare il colore di una label) potrebbe fare al caso tuo.. se ho capito bene quello che ti serviva
Il problema è che se anche tu aggiorni le variabili lui non le considera finchè tkainter non perde il controllo.
La cosa è ancora piu' problematica se la richiesta di aggiornamento arriva da una periferica che "dovrebbe" riusciere a interrompere momentaneamente il MONOPOLIO dell'interfaccia grafica e farmi aggiornare il colore del pulsante.
La mia ricerca è nel comando da utilizzare per questo.
Intanto Grazie.... se hai idee da suggerire non esitare,,,,

forse rileggendo non ho capito bene il problema... il tuo problema non è refreshare tkinter, ma il fatto che il raspberry rimanga in standby finchè non chiudi tkinter... è così?
La cosa è ancora piu' problematica se la richiesta di aggiornamento arriva da una periferica che "dovrebbe" riusciere a interrompere momentaneamente il MONOPOLIO dell'interfaccia grafica
C'è qualcosa che non quadra.

O il programma è strutturato tramite due o più thread/processi indipendenti, e allora può esserci qualcuno che vuole qualcosa dall'altro in modo asincrono... oppure l'unico processo in corso è il mainloop della GUI, e in tal caso è la GUI che deve controllare periodicamente la periferica e agire di conseguenza. Per i compiti periodici si può usare il metodo after:
try:
    import Tkinter as tk
except:
    import tkinter as tk

#-------------------------------------------------------------
def recall(msg):
    msg = msg[1:] + msg[:1]
    lab.configure(text=msg[:16])
    root.after(100, recall, msg)

#-------------------------------------------------------------
root = tk.Tk()
root.resizable(False, False)

frame = tk.Frame(root, relief=tk.RAISED, border=1, bg='black')
frame.pack(padx=16, pady=16)

lab = tk.Label(
    frame, relief=tk.SUNKEN, border=1,
    bg='#0D7FFF', fg='white', width=18, height=1,
    font=('monospace', 14, 'normal')
    )
lab.pack(pady=8, padx=8, ipady=4)

recall('               '
       'THE  QUICK  BROWN  FOX  JUMPS  OVER  THE  LAZY  DOG')

root.mainloop()
Naturalmente tutte le altre funzioni/metodi non devono bloccare il mainloop congelando la GUI, altrimenti anche 'recall' non viene chiamata.

In un programma con GUI il mainloop comanda sempre, tutte le altre funzioni devono solo gestire nel più breve tempo possibile gli eventi che la GUI ha rilevato.

Se ci sono attività cicliche che richiedono molto tempo, la loro esecuzione va scomposta in molti passaggi veloci chiamati dal mainloop.


--- Ultima modifica di Claudio_F in data 2017-11-26 10:14:14 ---
*** Il codice va evidenziato con il simbolo di fianco ai colori per non perdere l'indentazione ***
Salve a tutti , intanto grazie per le risposte; dalla quali prenderò spunto per fare delle prove.
Il punto comunque è questo:




Io ho un’interfaccia da noi progettata(siamo due amici) che controlla un movimento elettro meccanico; deve gestire un avanzamento di un carrello , un taglio, dei fine corsa...

Quindi il problema era quello di fare in modo di avere un’interfaccia Tkinter per impostare i parametri di spostamento e di taglio; dopo di che ci sono dei fine corsa, i quali mi danno la posizione del carrello che si muove.

In base a dove è il carrello , il fine corsa mi abilita/disabilita dei button e delle label informative.

Ecco il perché devo riuscire a “togliere il controllo” da Tkinter, altrimenti non mi permette di controllare l’evolversi delle operazioni.

Non mancherò di chiedere ancora suggerimenti/aiuto se avrò ancora del dubbi/problemi.

Grazie a tutti.




Alberto
------
Alberto
In base a dove è il carrello , il fine corsa mi abilita/disabilita dei button e delle label informative.
Ecco il perché devo riuscire a “togliere il controllo” da Tkinter, altrimenti non mi permette di controllare l’evolversi delle operazioni.
Direi che è il contrario, sei tu a tenere bloccato Tkinter monopolizzando il tempo, e quindi congelando la GUI.

Come detto nell'altro thread con il metodo 'configure' dei widget cambi le proprietà, ma poi bisogna anche permettere a Tkinter di aggiornare la grafica, e i modi sono due, o si chiama il metodo 'update' del singolo widget, o si chiama il metodo 'update_idletasks' della root, che permette la gestione degli eventi accumulati in coda.

Altrimenti bisogna riscrivere la propria logica in modo non bloccante.
*** Il codice va evidenziato con il simbolo di fianco ai colori per non perdere l'indentazione ***


Pagina: 1



Esegui il login per scrivere una risposta.