activation (rond noirci) d'un radiobouton + thread ?

Bonjour,
je veux lancer des programmes à l’aide de radiobouton. Dans le cas d’un flatpak, il faut un certain temps pour l’ouvrir. Dans ce cas le radiobouton ne s’active qu’après la fermeture du flatpak correctement lancé. J’ai pensé que c’était une histoire de thread mais je n’y arrive visiblement pas. Un petit coup de main serait le bienvenu.

def task():
	if var.get() == 1:
		var.set(1)
	elif var.get() == 2:
		var.set(2)

def run_app():
	if var.get() == 1:
		wr_ge='flatpak run org.gimp.GIMP'
		subprocess.run(wr_ge, shell=True)
	elif var.get() == 2:
		subprocess.Popen('/usr/bin/pdfarranger')

fen = Tk()
fen.geometry('350x100+1200+300')
var = IntVar()
c1 = Radiobutton(fen, text='GIMP : éditeur graphique',variable=var, bg="bisque", command=run_app, value = 1)
c1.place(x=10,y=10)
c2 = Radiobutton(fen, text='PDFarranger : gestionnaire PDF',variable=var, bg="bisque", command=run_app, value = 2)
c2.place(x=10,y=40)
t1 = Thread(target=task)
t1.start()
fen.mainloop()
t1.join()

Bonjour @mapommfj !

Je ne suis pas un habitué de tk mais j’aime beaucoup utiliser le module queue pour dialoguer entre des threads.

Dans cet exemple le “main thread” géré par tk utilise queue.put pour donner des instructions au worker_thread, le queue.put n’est pas bloquant donc le thread tk n’est jamais bloqué.

Le worker thread lui utilise queue.get pour attendre du travail (c’est bloquant, donc tant que la queue est vide, le worker thread ne fait rien).

J’ai implémenté deux tâches : run et exit, la première pour exécuter une commande et la seconde pour faire quitter le thread proprement.

Par contre vu que c’est des radio-button j’imagine qu’il faut tuer l’application qui s’exécute lorsqu’elle est dé-selectionnée ? Je n’ai pas implémenté ce comportement dans le doute.

import subprocess
from tkinter import Tk, IntVar, Radiobutton
from threading import Thread

from queue import Queue

task_queue = Queue()


def worker_thread():
    while True:
        print("Waiting for tasks...")
        task, *task_args = task_queue.get()
        if task == "exit":
            task_queue.task_done()
            return
        elif task == "run":
            print("Running", task_args)
            subprocess.run(task_args)
            task_queue.task_done()


def run_app():
    if var.get() == 1:
        task_queue.put(("run", 'flatpak', 'run', 'org.gimp.GIMP'))
    elif var.get() == 2:
        task_queue.put(("run", '/usr/bin/pdfarranger'))



fen = Tk()
fen.geometry('350x100+1200+300')
var = IntVar()
c1 = Radiobutton(fen, text='GIMP : éditeur graphique',variable=var, bg="bisque", command=run_app, value = 1)
c1.place(x=10,y=10)
c2 = Radiobutton(fen, text='PDFarranger : gestionnaire PDF',variable=var, bg="bisque", command=run_app, value = 2)
c2.place(x=10,y=40)
t1 = Thread(target=worker_thread)
t1.start()
fen.mainloop()

task_queue.put(("exit",))
task_queue.join()
t1.join()

Merci @mdk , je vais regarder ta proposition.

cela marche super bien (je croyais qu’il fallait installer un module queue, mais non).
Je présume que “run” aurait pû être remplacé par un nom quelconque
et idem pour task_args ?

Exact, run et exit sont juste des chaînes de caractères, task_args c’est juste un nom de variable, tu fais ce que tu veux avec.

Par contre attention a bien toujours exécuter un appel à queue.task_done() pour chaque appel à queue.get(), sinon la file perd le fil (haha) de ce qui est fait et pas fait, et tu ne pourras plus jamais la queue.join().

OK et merci pour ton aide précieuse