Pygtk-Glade lancement d'un MultiThread sans geler la fenêtre
Bonjour à tous,
je m'explique, je suis entrain de m'amuser à faire un petit serveur (de tchat).
Pour l'exemple j'ai créer une fenêtre glade avec un bouton et un TextBox (Je sait ... petite réminiscence VB je ferrai 2 ave patter et un ave Maria !!)
Le bouton déclenche une fonction START_SRV() qui a son tour déclenche le Multi-Thread serveur qui va attendre les connexion des clients.
le problème c'est que des que je presse mon bouton ma fenêtre gèle !!!
Pour l'exemple j'ai retirer tout les test que j'avais fait avec gtk.gdk.Thread_init() mais je l'ai essayer dans tout les sens !!!
Je comprend bien qu'il faudrait que ma GUI et mon serveur soit des Thread séparé mais dans la pratique ... je fait comment ? ... parce que j'ai beau tout essayer je vois bien qu'en fait je lance un Thread dans un Thread.
je vous ai mi ci dessous :
- le fichier qui démarre ma GUI
- La fonction START-SRV() (Sans les import)
- La class du serveur (Pardon s'il s'appel ThreadClient ... pas encore changé !! :-) )
Si quelqu'un arrive a me dépanner c'est génial parce que la je suis vraiment dans les choux :-)
Je vous remercie tous d'avance :-)
P.S: Pardon pour la propreté du code et les 2 ou 3 truc bizarre mais suis débutant. :-)
Code------
Gui [TestThread.py]
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
import pygtk
pygtk.require("2.0")
import gtk
import gtk.glade
from ApiCtrlCommun import START_SRV
class monprogramme:
def __init__(self):
self.widgets = gtk.Builder()
self.widgets.add_from_file('test.glade')
self.widgets.connect_signals(self)
def autoConnectb(self):
eventHandlers = {}
for (itemName,value) in self.__class__.__dict__.items():
if callable(value) and itemName.startswith('gtk_'):
eventHandlers[itemName[4:]] = getattr(self,itemName)
self.widgets.signal_autoconnect(eventHandlers)
def delete(self, source=None, event=None):
gtk.main_quit()
def on_button1_clicked(self, source=None, event=None):
START_SRV("localhost",40000)
return True
if __name__ == '__main__':
app = monprogramme()
gtk.main() |
START_SRV [ApiCtrlCommun.py]
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
def START_SRV(HOST,PORT):
mySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
myThreadClient=ThreadClient
try:
mySocket.bind((HOST, PORT))
except socket.error:
print "La liaison du socket à l'adresse choisie a échoué."
sys.exit()
print "Serveur prêt, en attente de requêtes ..."
mySocket.listen(5)
# Attente et prise en charge des connexions demandées par les clients :
conn_client = {} # dictionnaire des connexions clients
while 1:
connexion, adresse = mySocket.accept()
# Créer un nouvel objet thread pour gérer la connexion :
th = myThreadClient(connexion,conn_client)
th.start()
print th
# Mémoriser la connexion dans le dictionnaire :
it = th.getName() # identifiant du thread
conn_client[it] = connexion
print "Client %s connecté, adresse IP %s, port %s." %\
(it, adresse[0], adresse[1])
# Dialogue avec le client :
connexion.send("Vous êtes connecté. Envoyez vos messages.") |
Thread Serveur [ApiNetwork.py]
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
import threading
class ThreadClient(threading.Thread):
#dérivation d'un objet thread pour gérer la connexion avec un client
def __init__(self, conn ,client_return):
threading.Thread.__init__(self)
self.connexion = conn
self.client_ret=client_return
self.str_ret = "Serveur ok"
return self.str_ret
def run(self):
# Dialogue avec le client :
nom = self.getName() # Chaque thread possède un nom
while 1:
msgClient = self.connexion.recv(1024)
if msgClient.upper() == "FIN" or msgClient =="":
break
message = "%s> %s" % (nom, msgClient)
print message
# Faire suivre le message à tous les autres clients :
for cle in self.client_ret:
if cle != nom: # ne pas le renvoyer à l'émetteur
self.client_ret[cle].send(message)
#conn_client[cle].send(message)
# Fermeture de la connexion :
self.connexion.close() # couper la connexion côté serveur
del self.client_ret[nom]
#del conn_client[nom] # supprimer son entrée dans le dictionnaire
print "Client %s déconnecté." % nom
# Le thread se termine ici |