Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 09/02/2020, à 10:47

Compte supprimé

[Résolu]Programmation parallèle avec tkinter

Bonjour,
Avec tkinter j'ai deux images que je bouge l'une après l'autre, soit deux boucles disctinctes qui s'executent l'une après l'autre.
Je souhaite que ces images se mouvent simultanément. (que ces boucles distinctes s'executent simultanément)

question : quel module utiliser dans mon cas? je vois qu'on parle du module de multiprocessing ou threading..
Peut on utiliser la programmation parallèle sans utiliser une Classe? (la structure actuelle de mon programme n'utilise pas la programmation objet)
Un exemple serait aussi le bienvenu.

Dernière modification par Compte supprimé (Le 23/02/2020, à 09:30)

#2 Le 09/02/2020, à 15:54

Ekel

Re : [Résolu]Programmation parallèle avec tkinter


Ekel
---
Jammy Jellyfish - KUbuntu Utilisateur n°16275
AMD Ryzen 5 5600G  | B550 GAMING X V2 | 16 Go | 22" + 22"

Hors ligne

#3 Le 09/02/2020, à 18:08

Compte supprimé

Re : [Résolu]Programmation parallèle avec tkinter

Bonjour Ekel,
Merci,
J'ai lu les 2 liens ...(Je n'ai pris le temps d'en étudier chaque exemple)
Pour le 1er, je le trouve plutôt théorique. Ai-je vraiment besoin de connaître toutes les subtilités concernant les itérables, les itérateurs pour arriver à mes fins?
Pour le deuxième, je n'ai pas vraiment trouvé d'info(code) concernant mon cas de figure. Je le relirais à tête reposée au cas où(je fatigue)... mais j'ai l'impression que ça traite plutôt sur comment traiter une tache sur plusieurs threads. 

Mais peut-être que le sujet est trop complexe pour mes connaissances actuelles... Dans tous les cas, un exemple comprenant l'exécution de deux boucles en parallèle m'épargnerait fatigue oculaire et neurone. Le sujet semble si vaste que je m'y perds...

#4 Le 10/02/2020, à 21:22

Ekel

Re : [Résolu]Programmation parallèle avec tkinter

Bonsoir,

Je ne saurai aider alors davantage car je ne suis pas développeur et que j'avais parcouru ces deux articles lors de leur parution.

Je pense que tu en connais bien plus que moi sur ce langage.

Cordialement.


Ekel
---
Jammy Jellyfish - KUbuntu Utilisateur n°16275
AMD Ryzen 5 5600G  | B550 GAMING X V2 | 16 Go | 22" + 22"

Hors ligne

#5 Le 11/02/2020, à 08:51

Compte supprimé

Re : [Résolu]Programmation parallèle avec tkinter

Bonjour,
D'accord, merci pour les liens..
Moi non plus je ne suis pas développeur, je débute et je n'ai réalisé que des bricoles... wink

#6 Le 11/02/2020, à 14:54

melixgaro

Re : [Résolu]Programmation parallèle avec tkinter

salut,

multiprocessing supplante threading. Le module threading permet de démarrer plusieurs fils mais ils sont tous rattachés au même processeur. Donc si la tâche n'est pas limitée par le processeur, par ex. elle n'en prend que 20%, tu peux lancer cinq fils sur le même processeur pour exploiter au maximum la puissance de calcul tout en s'assurant que chaque tâche utilise toutes les ressources qu'elle voudrait utiliser (5 × 20 = 100). Le module multiprocessing permet de faire du multi-fils ou threading (comme le module threading) mais permet aussi de faire du multi-processeur ou multiprocessing, c'est-à-dire lancer plusieurs tâches sur des processeurs différents. Donc si la tâche est limitée par le processeur (elle en utilise 100%) et si tu veux faire tourner deux instances de la tâche en question, il faudra lancer la deuxième instance sur un second processeur (via multiprocessing) pour que chacune tourne à plein régime.
Si tu n'en connais aucun des deux, je conseille d'aller directement vers multiprocessing. C'est aussi compliqué d'appréhender l'un ou l'autre.

Voir les pages en anglais de Python Module Of The Week à cette adresse pour des exemples simples. Jette un œil aux liens portant sur les modules threading ou multiprocessing listés dans la page citée.


Linux depuis ~2007. Xubuntu seulement.

Hors ligne

#7 Le 11/02/2020, à 16:15

Compte supprimé

Re : [Résolu]Programmation parallèle avec tkinter

Salut melixgaro,
C'est exactement ce que je cherchai smile
Je te remercie pour ton lien et tes explications.

[hs]
Quand j'ai lu voir les pages en anglais , je me suis dit que je ne vais rien y comprendre... mais non j'ignore pourquoi mais la traduction de google est parfaite. Souvent le code en lui-même est traduit ce qui m'oblige à regarder le texte original et celle de la traduction (qui souvent ne ressemble à rien.) C'est vite galère (dans ce cas j'utilise Deepl, mais n'utilisant que la version gratuite, j'ai des traductions tronquées ... et la aussi ça devient vite galère de traduire par bride)

Dernière modification par Compte supprimé (Le 11/02/2020, à 16:17)

#8 Le 11/02/2020, à 18:01

melixgaro

Re : [Résolu]Programmation parallèle avec tkinter

De rien wink


Linux depuis ~2007. Xubuntu seulement.

Hors ligne

#9 Le 11/02/2020, à 18:03

melixgaro

Re : [Résolu]Programmation parallèle avec tkinter

Oui, désolé pour les réfs. en anglais. J'ai ça sous le coude depuis des années et comme c'est plutôt clair pour une première approche (mais ça ne suffit pas pour passer maître jedi !), je n'ai pas vraiment cherché d'autres pas-à-pas.


Linux depuis ~2007. Xubuntu seulement.

Hors ligne

#10 Le 12/02/2020, à 12:24

Compte supprimé

Re : [Résolu]Programmation parallèle avec tkinter

Bonjour,
Je n'arrive pas à appliquer les exemples du lien sur un code tkinter...
avec des boucles avec des prints c'est ok, mais par exemple avec le code ci dessous me renvoit une erreur :

python3 /home/fab/bidon.py 
XIO:  fatal IO error 11 (Resource temporarily unavailable) on X server ":0.0"
      after 329 requests (329 known processed) with 2 events remaining.

XIO:  fatal IO error 11 (Resource temporarily unavailable) on X server ":0.0"
      after 318 requests (318 known processed) with 0 events remaining.
import tkinter as tk
import time
import multiprocessing

fen = tk.Tk()
can=tk.Canvas(fen,width=1680,height=1080,background='black')
can.pack()

photo = tk.PhotoImage(file="/home/fab/Téléchargements/crane2.png")
photo2 = tk.PhotoImage(file="/home/fab/Téléchargements/crane3.png")
bidulle = can.create_image(0,0,anchor= 'nw', image=photo)
bidulle2 = can.create_image(1300,0,anchor= 'nw', image=photo2)


def fonctiond():
    for i in range(0,1300,2):
        can.move(bidulle,2,0)
        fen.update()
    can.delete(bidulle)
        
def fonctiong():
    for i in range(1300,0,-2):
        can.move(bidulle2,-2,0)
        fen.update()
    can.delete(bidulle2)
        
p = multiprocessing.Process(target=fonctiond)
p2 = multiprocessing.Process(target=fonctiong)
p.start()
p2.start()
##fonctiond()
##fonctiong()

Qu'en est il?

#11 Le 12/02/2020, à 20:14

melixgaro

Re : [Résolu]Programmation parallèle avec tkinter

Là ça doit être une erreur purement liée à la partie graphique. Si tu mets une temporisation après fen.update()

import time   # en en-tête
time.sleep(0.5)   # après les 2 fen.update(); joue sur le temps si nécessaire

ou alors (plus probable)

l'accès simultané à la ressource n'est pas possible (les deux fen.update() ont lieu au même moment). Dans ce cas, il faut utiliser un verrou (cherche avec les mots-clefs python lock multiprocessing dans ton moteur de recherche) pour vérouiller la ressource dans fonctiond le temps qu'elle s'exécute, puis libérer la ressource pour que fonctiong puisse à son tour s'approprier la ressource et faire son affaire et ainsi de suite.

Je peux lancer ça chez moi (en remplaçant les deux png évidemment) ? l'exemple est autonome ?


Linux depuis ~2007. Xubuntu seulement.

Hors ligne

#12 Le 12/02/2020, à 20:53

Compte supprimé

Re : [Résolu]Programmation parallèle avec tkinter

Avec les time.sleep j'obtiens les mêmes erreurs . Je vais rechercher du côté des verrous, voir ce que je trouve...

Je peux lancer ça chez moi (en remplaçant les deux png évidemment) ? l'exemple est autonome ?

Oui si ton ecran est HD (le caneva fait 1680*1080). Selon la taille de tes png , celui de droite sera juste tronqué ou mal placé, ce qui n'est pas invalidant pour le test . La boucle de la fonctiond() fait bouger son png de droite à gauche . La boucle de la fonctiong() fait bouger l'autre png de gauche à droite. Le but étant que les deux png se déplacent en même temps et non pas l'un après l'autre .
Il faut rajouter fen.destroy() à la fin du code pour sortir

#13 Le 12/02/2020, à 21:35

melixgaro

Re : [Résolu]Programmation parallèle avec tkinter

ah, je crois que j'ai enfin compris ce que ça devait faire…


Linux depuis ~2007. Xubuntu seulement.

Hors ligne

#14 Le 12/02/2020, à 21:54

melixgaro

Re : [Résolu]Programmation parallèle avec tkinter

Je pense que ce n'est pas un cas où il faut du multi-fils. Utilise cette fonction (en commentant donc les p.start() et p2.start()) :

def fonction_simult():
   for i in range(0, 1300, 2):
      can.move(bidulle,2,0)
      can.move(bidulle2,-2,0)
      fen.update()
      time.sleep(0.025)
   can.delete(bidulle)
   can.delete(bidulle2)

Linux depuis ~2007. Xubuntu seulement.

Hors ligne

#15 Le 12/02/2020, à 22:52

Compte supprimé

Re : [Résolu]Programmation parallèle avec tkinter

Là tu joues en touche wink .
Je n'ai donné ce code que pour un exemple très simplifié .
Dans le cas d'une mise en situation réelle, il peut y avoir des boucles complètement différentes et pas que des boucles d'ailleurs, des affichages divers et variées , avec des outils touts aussi variés, des évent, calcul et autre. Imagine le cas d'un jeu style case brique... ou pire, pour les maîtres Jedi : Space Ivanders

Je ne trouve pas vraiment d'info sur l'erreur rencontrée. J'ai cherché un peu du côté de lock , mais pour l'instant rien de probant . Peut-être faut-il utiliser une queue. ça revient dans quelques lectures. Mais je n'ai en trouvé de code sur lequel m'appuyer et je ne sais même pas si c'est dans cette direction que je dois chercher.

#16 Le 12/02/2020, à 23:19

melixgaro

Re : [Résolu]Programmation parallèle avec tkinter

Je tiens à souligner qu'avec le multi-fils ou multi-processeurs, tu n'as pas de contrôle sur qui s'exécute quand. Avec l'exemple donné, j'avais l'impression que le résultat attendu était un glissement des deux figures simultané (quand l'une se déplace de n * 2 pixels, l'autre se déplace de -n * 2 pixels, en même temps), vers leur côté opposé. Or, avec ta première proposition, on peut imaginer tous les scénarios possibles ; par exemple, la figure de gauche se déplace de 30 * 2 pixels, quand celle de droite n'a pas encore bougé. Pour moi, il faut un mécanisme de synchronisation, pour pas qu'une fonction de déplacement prenne du retard sur l'autre.


Linux depuis ~2007. Xubuntu seulement.

Hors ligne

#17 Le 13/02/2020, à 00:09

Compte supprimé

Re : [Résolu]Programmation parallèle avec tkinter

melixgaro a écrit :

Pour moi, il faut un mécanisme de synchronisation, pour pas qu'une fonction de déplacement prenne du retard sur l'autre.

Oui certainement.
J'ai cru comprendre que pour cela, une solution consiste à creer une queue avec les actions à entreprendre, et la consulter/vider régulièrement. Avec Tkinter on peut utiliser root.after() pour synchroniser des fonctions (appel d'une fonction dans x millisecondes). ça reste quand même bien abstrait pour moi(pas sûr que j'ai compris), et sans code explicité sur le sujet, je ne serais la mettre en œuvre ...

#18 Le 13/02/2020, à 04:42

Roschan

Re : [Résolu]Programmation parallèle avec tkinter

La programmation distribuée est un sujet infiniment plus complexe et périlleux que la programmation objet, n'essaye pas de brûler les étapes : si tu veux que tes 2 images bougent simultanément, fait les juste bouger dans la même boucle comme le propose @melixgaro, je t'assure qu'on peut faire des choses largement plus compliquées qu'un Space Invaders en restant dans un seul fil d'exécution : se lancer dans du multithreading pour ça, ce serait vraiment VRAIMENT beaucoup se compliquer la vie

La boucle de @melixgaro peut appeler des fonctions qui se chargeraient d'isoler le code pour un tour de boucle de l'image 1 et le code pour un tour de boucle de l'image 2 : dans le cas de ton exemple simplifié, le code d'une telle fonction ne fait qu'une ligne, mais ça vaut le coup quand même.

Hors ligne

#19 Le 13/02/2020, à 05:04

Roschan

Re : [Résolu]Programmation parallèle avec tkinter

import tkinter as tk
import time

fen = tk.Tk()
can = tk.Canvas(fen, width=1200, height=600, background='black')
can.pack()

ALL_PICS = []

class MovablePicture():
	def __init__(self, image_path, x_init, y_init):
		self.photo = tk.PhotoImage(file=image_path)
		self.image_id = can.create_image(x_init, y_init, anchor='nw', image=self.photo)
		self.dx = 0
		self.dy = 0

	def set_directions(self, dx, dy):
		self.dx = dx
		self.dy = dy

	def do_action(self):
		can.move(self.image_id, self.dx, self.dy)

	def remove_from_canvas(self):
		can.delete(self.image_id)

################################################################################

def move_pictures():
	for i in range(500):
		for pic in ALL_PICS:
			pic.do_action()
		fen.update()
		time.sleep(0.1)

def delete_pictures():
	for pic in ALL_PICS:
		pic.remove_from_canvas()

################################################################################

image1 = MovablePicture("/home/roschan/Images/truc1.png", 0, 0)
image1.set_directions(2, 0)
ALL_PICS.append(image1)

image2 = MovablePicture("/home/roschan/Images/truc2.png", 1000, 0)
image2.set_directions(-2, 0)
ALL_PICS.append(image2)

move_pictures()
delete_pictures()

change les chemins et ce code là ça marche. Remarque que le traitement des images se fait en parcourant l'array, donc tu peux ajouter autant d'images que tu veux dans l'array le code ne changera pas des masses : notamment, ajouter autant d'aliens que tu veux à la chaîne

for i in range(8):
	image_alien = MovablePicture("/home/roschan/Images/monstre3.png", 1000 - i * 150, 0)
	image_alien.set_directions(-2, 0)
	ALL_PICS.append(image_alien)

move_pictures()
# blablabla
# appel d'une méthode avec un for qui parcourerait l'array pour changer les directions des aliens
# blablabla
delete_pictures()

(Si tu pars vraiment sur ce projet, mettre l'image du vaisseau dans le même array ne sera pas pertinent étant donné le code existant parce qu'il a des mouvements totalement indépendants du reste)

Dernière modification par Roschan (Le 13/02/2020, à 05:06)

Hors ligne

#20 Le 13/02/2020, à 09:30

Compte supprimé

Re : [Résolu]Programmation parallèle avec tkinter

Bonjour Roschan,
Tu as raison, je ne vais pas bruler les étapes, je vais me contenter de celles qui me sont à la portée de main.
Merci pour ton exemple, je vais revisiter une animation que j'avais écrite sans utiliser de classe, en m'inspirant de ta structure... smile

Je n'ai pas encore de projet défini.
Pour l'instant, je me crée des scenarios de déplacements, d'affichage, d'évents et d'actions que je m'applique à réaliser .Je veux que ceci fasse cela tandis que cela fait ceci ... wink
Selon ce que je veux faire cela m'interroge sur la façon de le faire. C'est ainsi que je procède pour apprendre.
L'interrogation qui m'a amené à la création de ce post était comment arriver à gérer un affichage 'simultané' de deux déplacements strictement différent (nous sommes donc dans le cas du vaisseau que tu évoques dans ta parenthèse). Je pensais que la façon d'y arriver était d'aborder la programmation parallèle (mais bon hors de ma portée), d'où le titre de ce post

#21 Le 13/02/2020, à 11:09

Compte supprimé

Re : [Résolu]Programmation parallèle avec tkinter

Roschan a écrit :

je t'assure qu'on peut faire des choses largement plus compliquées qu'un Space Invaders en restant dans un seul fil d'exécution

Question: On peut réaliser avec Tkinter ce type de jeu? .
ou dois-je nécessairement passer par pygame?
Je préfèrerais continuer à utiliser Tkinter car j'y ai déjà des repères, mais si il est nécessaire que je passe par pygame autant m'y appliquer dès maintenant .

#22 Le 14/02/2020, à 04:28

Roschan

Re : [Résolu]Programmation parallèle avec tkinter

pygame est plus compliqué dans un 1er temps mais à long terme ça te simplifiera la vie, notamment pour tout ce qui touche aux contrôles claviers (je ne sais même pas si ça existe avec tkinter)

Dernière modification par Roschan (Le 14/02/2020, à 04:29)

Hors ligne

#23 Le 14/02/2020, à 09:30

Compte supprimé

Re : [Résolu]Programmation parallèle avec tkinter

Si par contrôle clavier tu entends gestion des évènements claviers, ça existe déjà avec Tkinter:

 canevas.bind('<KeyPress-x>', Mafonction) 
Ceci a pour effet d'appeler la Mafonction si la touche x est appuyée

-----
Je me demande si pygame n'est pas pourvu de méthodes permettant justement de mieux gérer la synchronisation/indépendance des Sprites et qui permettraient de mieux appréhender le cas de mouvements strictement différents de Sprites. Je vais me renseigner sur le sujet.
Merci Roschan , merci Melixgaro pour votre participation,
Bien que je me pose toujours la question du comment faire, vous m'avez aidé à murir ma réflexion sur le sujet et notamment sur les threads smile
Je laisse ce post ouvert

Dernière modification par Compte supprimé (Le 14/02/2020, à 09:33)

#24 Le 23/02/2020, à 09:29

Compte supprimé

Re : [Résolu]Programmation parallèle avec tkinter

Bien que je me pose toujours la question du comment faire

En fait avec Tkinter on fait de la programmation événementielle. On peut tout gérer avec des after().

Pour ce qui est de l'utilisation de multiprocessing comme évoquée en 10 cela ne se fait pas. Éventuellement, on peut mettre l'ensemble de la classe Tk sous multiprocessing mais pas ses méthodes.

Je peux maintenant éditer en résolu smile

#25 Le 23/02/2020, à 11:33

melixgaro

Re : [Résolu]Programmation parallèle avec tkinter

Merci wink


Linux depuis ~2007. Xubuntu seulement.

Hors ligne