#python-3.x #sockets #tkinter #window
#python-3.x #сокеты #tkinter #окно
Вопрос:
- Я хотел бы подключить 2 компьютера, чтобы создать своего рода мессенджер, но я хотел бы использовать
tkinter
, чтобы иметь окна, и использовать кнопки и другие виджеты для создания интерфейса. - Итак, у меня есть 2 программы, одна из которых является клиентом, а другая — сервером.
- Для клиента это работает: отображается окно, и я могу отправить сообщение.
- Для сервера окно не отображается.
клиентская программа:
import socket
from tkinter import *
def envoyer_msg():
s.send(msg.get().encode())
fenetre=Tk()
fenetre.geometry("{}x{} {} {}".format(200,200,200,200))
texte=Label(fenetre,text="CLIENT",font=25)
texte.pack()
msg=StringVar()
saisie=Entry(fenetre,textvariable=msg,font=25)
saisie.pack()
bouton_envoyer=Button(fenetre,text="Envoyer",font=25,command=envoyer_msg)
bouton_envoyer.pack()
s = socket.socket()
s.connect(('127.0.0.1',12345))
и здесь серверная программа :
import socket
from tkinter import *
def envoyer_msg():
c.send(msg.encode())
fenetre=Tk()
fenetre.geometry("{}x{} {} {}".format(200,200,200,200))
texte=Label(fenetre,text="SERVEUR",font=25)
texte.pack()
msg=StringVar()
saisie=Entry(fenetre,textvariable=msg,font=25)
saisie.pack()
bouton_envoyer=Button(fenetre,text="Envoyer",font=25,command=envoyer_msg)
bouton_envoyer.pack()
print("1")
s = socket.socket()
port = 12345
s.bind(('', port))
s.listen(5)
c, addr = s.accept()
print ("Socket Up and running with a connection from",addr)
print("2")
while True:
rcvdData = c.recv(1024).decode()
print ("S:",rcvdData)
print("3")
Ответ №1:
Сначала вы должны вызвать mainloop()
явно, даже если вы используете IDE, созданную с tkinter
помощью Python IDLE. В противном случае графический интерфейс не будет отображаться при выполнении скрипта в терминале.
Графический интерфейс сервера не отображается, потому что while
цикл блокирует mainloop()
. Вам нужно поместить задачу обработки клиентского соединения в поток:
# server code
import socket
import threading
from tkinter import *
def envoyer_msg():
c.send(msg.get().encode())
fenetre=Tk()
fenetre.geometry("{}x{} {} {}".format(200,200,200,200))
texte=Label(fenetre,text="SERVEUR",font=25)
texte.pack()
msg=StringVar()
saisie=Entry(fenetre,textvariable=msg,font=25)
saisie.pack()
bouton_envoyer=Button(fenetre,text="Envoyer",font=25,command=envoyer_msg)
bouton_envoyer.pack()
def server_task():
global c
s = socket.socket()
port = 12345
s.bind(('', port))
s.listen(5)
while True:
print('waiting connection ...')
c, addr = s.accept()
print ("Socket Up and running with a connection from", addr)
while True:
try:
rcvdData = c.recv(1024).decode()
print ("Client:", rcvdData)
except ConnectionResetError:
print('Client disconnected')
break
# start the client connection handling thread
threading.Thread(target=server_task, daemon=True).start()
fenetre.mainloop()
То же самое относится и к стороне клиента:
# client code
import socket
import threading
from tkinter import *
def envoyer_msg():
s.send(msg.get().encode())
fenetre=Tk()
fenetre.geometry("{}x{} {} {}".format(200,200,400,200))
texte=Label(fenetre,text="CLIENT",font=25)
texte.pack()
msg=StringVar()
saisie=Entry(fenetre,textvariable=msg,font=25)
saisie.pack()
bouton_envoyer=Button(fenetre,text="Envoyer",font=25,command=envoyer_msg)
bouton_envoyer.pack()
def client_task():
global s
s = socket.socket()
s.connect(('127.0.0.1',12345))
while True:
try:
rcvdData = s.recv(1024).decode()
print('Server:', rcvdData)
except ConnectionResetError:
print('Server disconnected')
fenetre.destroy()
# start the server connection thread
threading.Thread(target=client_task, daemon=True).start()
fenetre.mainloop()
Поскольку вы хотите использовать графический интерфейс, лучше использовать Text
виджет для хранения одноранговых сообщений вместо использования print()
.