Can I close the DataCom thread before TKinter GUI exit? When I run the code into WING IDE closing the GUI the DataCom still running receiving packets from center. I tried to find something similar example none of them work.
from Tkinter import Tk, N, S, W, E, BOTH, Text, Frame,Label, Button,Checkbutton, IntVar,Entry
import socket
import sys
import os
import time
import datetime
from threading import Thread
data = ''
def timeStamped(fmt='%Y-%m-%d-%H-%M-%S_{fname}'):
return datetime.datetime.now().ctime()
def get_constants(prefix):
"""Create a dictionary mapping socket module constants to their names."""
return dict( (getattr(socket, n), n)
for n in dir(socket)
if n.startswith(prefix)
)
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.friend_check = IntVar()
self.parent = parent
self.initUI()
def initUI(self):
self.parent.title("Home.local")
self.PoolLabel = Label (text = "Pool Temperature:")
self.PoolLabel.grid(row=0,column=0,columnspan=2, sticky=W)
self.BasementLabel = Label (text = "Basement Conditions:")
self.BasementLabel.grid(row=3,column=0,columnspan=2, pady =10)
try:
datalist=data.split(':')
print datalist
self.cl_label=Label(text="")
self.cl_label.config(text=datalist[0].split(', ',1)[1])
self.cl_label.grid(row=1,column=0,columnspan=2,sticky='EW')
self.baselabelT=Label(text="")
self.baselabelT.config(text=datalist[1])
self.baselabelT.grid(row=4,column=0,columnspan=2,sticky='EW')
self.baselabelH=Label(text="")
self.baselabelH.config(text=datalist[2])
self.baselabelH.grid(row=5,column=0,columnspan=2,sticky='EW')
except IndexError:
datalist = 'null'
self.btn_Exit = Button(text="Exit", command = '')
self.btn_Exit.grid(row=10,column=2)
#self.update()
self.after(1000, self.initUI)
class DataCom(Thread):
def __init__(self, val):
Thread.__init__(self)
self.val = val
def run(self):
global data
families = get_constants('AF_')
types = get_constants('SOCK_')
protocols = get_constants('IPPROTO_')
# Create a TCP/IP socket
sock = socket.create_connection(('localhost', 10000))
print >>sys.stderr, 'Family :', families[sock.family]
print >>sys.stderr, 'Type :', types[sock.type]
print >>sys.stderr, 'Protocol:', protocols[sock.proto]
print >>sys.stderr
while True:
try:
# Send flag
message = 'INFO'
print >>sys.stderr, 'sending "%s" Length: %s' % (message,len(message))
sock.sendall(message)
amount_received = 0
amount_expected = len(message)
while amount_received < amount_expected:
data = sock.recv(1024)
amount_received += len(data)
if len(data) != 0:
print >>sys.stderr, 'Server received %s %s:Length %s' % (timeStamped(), data, len(data))
else:
sock.close()
print >>sys.stderr, 'No more data, closing socket'
break
if not data:
break
finally:
time.sleep(1)
def main():
myThread = DataCom(1)
myThread.setName('DataComThread')
myThread.start()
root = Tk()
root.geometry("600x450+900+300")
root.resizable(0,0)
app = Example(root)
root.config(background = "#FFFFFF") # ui debug
root.mainloop()
if __name__ == '__main__':
main()
Related
We are trying to use an ethernet communication model on the raspberry Pi that receives data from an Arduino in an infinite while loop. The response of the communication is then displayed onto the GUI which is running in parallel.
The flags are being received by the Pi but the gui does not display the required images.
from tkinter import *
from PIL import ImageTk,Image
from socket import *
import select
import numpy as np
from threading import Thread
from time import sleep
global data
data = None
timeout = 3 # timeout in seconds
msg = "test"
host = "192.168.1.101"
print ("Connecting to " + host)
port = 5000
s = socket(AF_INET, SOCK_STREAM)
print ("Socket made")
ready = select.select([s],[],[],timeout)
s.connect((host,port))
print("Connection made")
def func2():
while True:
data = s.recv(4096)
print("Data received")
print (data)
if __name__ == '__main__':
Thread(target = func2).start()
w=Tk()
w.geometry('1700x900')
w.configure(bg='#ffffff')
w.resizable(True,True)
w.title('SensorNode User Interface')
imagegreen = ImageTk.PhotoImage(Image.open("green.png"))
imagered = ImageTk.PhotoImage(Image.open("red.png"))
def func1():
while True:
if (data == 0):
Button(w,
image=imagered,
border=0,
bg='#ffffff',
activebackground='#ffffff').place(x=630,y=460)
sleep(0.1)
if (data == 1):
Button(w,
image=imagegreen,
border=0,
bg='#ffffff',
activebackground='#ffffff').place(x=630,y=460)
sleep(0.1)
if __name__ == '__main__':
Thread(target = func1).start()
w.mainloop()
I'm making an application that reads serial data coming from the sensors on an arduino board. Problems arise when trying to use the matplotlib.animation class to make a live graph of said data. The GUI widgets become unresponsive when the plotting is taking place. As far as i've understood, making the serial reading process run on its own thread could potentially solve the issue. I'm having trouble understanding how this could be made so that it is compatible with the FuncAnimation-subclass.
def read_serial_data(port, bauds=9600):
s = serial.Serial(port, bauds)
line = s.readline()[0:-2]
return line
def getPorts():
return [port.device for port in serial.tools.list_ports.comports(include_links=False)]
class GUI():
def __init__(self):
self.root = Tk.Tk()
self._fig = plt.figure()
self.root.title('Measurement Dashboard')
self.root.state('normal')
self.root.config(background='#ffffff')
self._canvas = FigureCanvasTkAgg(self._fig, self.root)
self._canvas.get_tk_widget().grid(column = 1, row = 1)
self._canvas.draw()
self._animate = None
self._ax = self._fig.add_subplot(111)
self._ax.yaxis.grid(True, color = 'black', linestyle='--')
self._ax.xaxis.grid(True, color = 'black', linestyle='--')
self._ax.set_xlabel('time')
self._ax.set_ylabel('CO2')
self.filename = Tk.StringVar()
self.entry = ttk.Entry(self.root, textvariable = self.filename)
self.entry.grid(column = 2, row = 2)
self.info_var = Tk.StringVar()
self.info_entry = ttk.Entry(self.root, textvariable = self.info_var)
self.info_entry.grid(column = 2, row = 3)
self.port = Tk.StringVar()
self.ports = getPorts()
self._cb = ttk.Combobox(self.root, textvariable= self.port, values = self.ports)
self._cb.grid(column = 2, row = 1)
self.start_button = Tk.Button(self.root, text = 'Start', command = self.plot)
self.start_button.grid(column = 1, row = 2)
self.save_button = Tk.Button(self.root, text = 'Save info', command = self.save_info)
self.save_button.grid(column = 2, row = 4)
def save_info(self):
global info
info = self.info_var.get()
def start(self):
self.root.mainloop()
def plot(self):
if self._animate is None:
self.scope = Scope(self._ax, self.filename.get())
self._canvas.draw_idle()
self._animate = animation.FuncAnimation(self._fig, self.scope.animate, frames = self.update, interval=2000, blit=False)
def update(self):
line = read_serial_data(self.port.get())
data = line.decode('utf-8')
yield data
time = datetime.now()
duration = time - start_time
measurement = {'time': time, 'dur': duration.seconds, 'CO2': data, 'info': info}
write_csv_line(self.filename.get(), measurement)
self.root.after(10000, self.update)
if __name__ == "__main__":
gui = GUI()
gui.start()
thread = Thread(target=read_serial_data,args=(gui.port,))
thread.start()
You don't really need another thread but can do this using non-blocking IO on th eserial port and make use of the Tkinter after call to manage the poll interval. pyserial provices inWaiting to test if the device has input waiting to be read. If there are bytes waiting, read just those.
Here is an example reader class to read lines from a serial device and post them to the application handler method once a complete line is read.
class Reader(Serial):
def __init__(self, *args, **kwargs):
self.buffer = ''
super(Reader, self).__init__(*args, **kwargs)
def monitor(self, w, interval=10):
n = self.inWaiting()
if n != 0:
data = self.read(n).decode('ascii')
self.buffer = self.buffer + data
ndx = self.buffer.find("\n")
if ndx != -1:
line = self.buffer[:ndx+1]
self.buffer = self.buffer[ndx+1:]
w.after_idle(lambda: w.parse_input(line))
w.after(interval, lambda: self.monitor(w, interval))
Used like:
app = <tkinter application class instance>
reader = Reader(port, baudrate, timeout=0)
reader.flushInput()
reader.monitor(app, 10)
app.mainloop()
In this case, it will call a parse_input method on the app instance whenever a line is read (delimited by a newline).
If you decide to use a thread, then you need a Queue to pass the data to the Tkinter UI thread and must ensure you don't call Tkinter methods from the worker thread.
I am trying to make a simple video chat application with 2 participants. Here the JoinClient is the a PyQt UI for entering code and accessing the meeting. This window is then redirected to the CallClient where the actual meeting takes place. I am using cv2.VideoCapture(0) to get a video frame and then using PIL and PyQt I am processing that frame and signalling the Qpixmap of the same. However, I am sending a raw frame to the server, which is then sent to the second user by the server itself. I am doing something similar with audio using pyaudio and audio streams to input and output audio. Before adding the socket programming, the application works just fine, but as I add the socket programming the application after opening the CallClient stops responding. I am unsure as to why this happens or how I could fix it.
client.py
from PyQt5 import QtCore, QtGui, QtWidgets
import meetingui
import joinui
from PIL.ImageQt import ImageQt
from PIL import Image
import cv2
import pyaudio
import network as net
class Worker(QtCore.QObject):
finished = QtCore.pyqtSignal()
cam_signal = QtCore.pyqtSignal(bool)
mic_signal = QtCore.pyqtSignal(bool)
p1video_feed_signal = QtCore.pyqtSignal(QtGui.QPixmap)
p2video_feed_signal = QtCore.pyqtSignal(QtGui.QPixmap)
def __init__(self, parent=None):
QtCore.QObject.__init__(self, parent=parent)
self.leave_call = False
self.camera_status = False
self.mic_status = False
self.audio_interface = pyaudio.PyAudio()
self.chunk = 2048
self.sample_format = pyaudio.paInt16
self.channels = 2
self.fs = 44100
def run(self, name, code):
network = net.Network({'name': name, 'code': code})
person = {}
while not self.leave_call:
# Get self mic data
if self.mic_status:
audio_data = self.stream.read(self.chunk)
person['audio'] = audio_data
else:
person['audio'] = None
# get self camera data
if self.camera_status and self.video_feed.isOpened():
check, self.p1frame = self.video_feed.read()
if check:
self.p1frame = cv2.cvtColor(self.p1frame, cv2.COLOR_BGR2RGB)
self.p1frame = cv2.flip(self.p1frame, 1)
self.PILp1frame = Image.fromarray(self.p1frame).convert('RGB')
self.Qtp1frame = ImageQt(self.PILp1frame)
self.p1video_feed_signal.emit(QtGui.QPixmap.fromImage(self.Qtp1frame))
person['video_frame'] = self.p1frame
else:
person['video_frame'] = None
else:
person['video_frame'] = None
# send self data and receive person2 data
p2 = network.send(person)
if p2:
if p2['audio']:
self.stream.write(p2['audio'])
if p2['video_frame']:
self.PILp2frame = Image.fromarray(p2['video_frame']).convert('RGB')
self.Qtp2frame = ImageQt(self.PILp2frame)
self.p2video_feed_signal.emit(QtGui.QPixmap.fromImage(self.Qtp2frame))
else:
self.p2video_feed_signal.emit(QtGui.QPixmap('Icons\\img_avatar.png'))
else:
break
self.finished.emit()
def leave(self):
self.audio_interface.terminate()
self.leave_call = True
def toggle_cam(self):
if not self.camera_status:
self.video_feed = cv2.VideoCapture(0)
self.camera_status = True
else:
self.camera_status = False
self.video_feed.release()
self.p1video_feed_signal.emit(QtGui.QPixmap('Icons\\img_avatar.png'))
self.cam_signal.emit(self.camera_status)
def toggle_mic(self):
if not self.mic_status:
self.stream = self.audio_interface.open(format=self.sample_format,
channels=self.channels,
rate=self.fs,
frames_per_buffer=self.chunk,
input=True,
output=True)
self.mic_status = True
else:
self.mic_status = False
self.stream.stop_stream()
self.stream.close()
self.mic_signal.emit(self.mic_status)
class CallClient(QtWidgets.QWidget, meetingui.Ui_MeetingWindow):
stop_signal = QtCore.pyqtSignal()
toggle_cam_signal = QtCore.pyqtSignal()
toggle_mic_signal = QtCore.pyqtSignal()
def __init__(self, code, name, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setupUi(self)
self.P1_name = name
self.MeetCode = code
self.setWindowTitle(f'Video Call App (Meeting Code - {code})')
# Signals and Slots
self.thread = QtCore.QThread()
self.worker = Worker()
self.stop_signal.connect(self.worker.leave)
self.toggle_cam_signal.connect(self.worker.toggle_cam)
self.toggle_mic_signal.connect(self.worker.toggle_mic)
self.worker.moveToThread(self.thread)
self.thread.started.connect(lambda: self.worker.run(self.P1_name, self.MeetCode))
self.worker.cam_signal.connect(lambda status: self.handleCam(status))
self.worker.mic_signal.connect(lambda status: self.handleMic(status))
self.worker.p1video_feed_signal.connect(lambda video_feed: self.setP1Frames(video_feed))
self.worker.p2video_feed_signal.connect(lambda video_feed: self.setP2Frames(video_feed))
self.worker.finished.connect(self.thread.quit)
self.worker.finished.connect(self.worker.deleteLater)
self.thread.finished.connect(self.thread.deleteLater)
self.thread.finished.connect(self.close)
self.thread.start()
self.leaveBtn.clicked.connect(self.stop_thread)
self.cameraBtn.clicked.connect(self.toggle_cam)
self.micBtn.clicked.connect(self.toggle_mic)
def stop_thread(self):
self.stop_signal.emit()
self.close()
def toggle_cam(self):
self.toggle_cam_signal.emit()
def toggle_mic(self):
self.toggle_mic_signal.emit()
def handleCam(self, cam_status):
if cam_status:
cam_icon = QtGui.QIcon()
cam_icon.addPixmap(QtGui.QPixmap("Icons\\icons8-camera-96.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.cameraBtn.setIcon(cam_icon)
self.cameraBtn.setStyleSheet(
"border:none;border-radius: 35px;padding: 10px;background-color: rgb(255, 255, 255);")
else:
cam_icon = QtGui.QIcon()
cam_icon.addPixmap(QtGui.QPixmap("Icons\\no-cam-icon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.cameraBtn.setIcon(cam_icon)
self.cameraBtn.setStyleSheet(
"border:none;border-radius: 35px;padding: 10px;background-color: rgb(204, 0, 0);")
def handleMic(self, mic_status):
if mic_status:
mic_icon = QtGui.QIcon()
mic_icon.addPixmap(QtGui.QPixmap("Icons\\icons8-microphone-96.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.micBtn.setIcon(mic_icon)
self.micBtn.setStyleSheet(
"border:none;border-radius: 35px;padding: 10px;background-color: rgb(255, 255, 255);")
else:
mic_icon = QtGui.QIcon()
mic_icon.addPixmap(QtGui.QPixmap("Icons\\no-mic-icon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.micBtn.setIcon(mic_icon)
self.micBtn.setStyleSheet(
"border:none;border-radius: 35px;padding: 10px;background-color: rgb(204, 0, 0);")
def setP1Frames(self, pixmap):
self.Person1_Self.setPixmap(pixmap)
def setP2Frames(self, pixmap):
self.Person2_Opposite.setPixmap(pixmap)
class JoinClient(QtWidgets.QWidget, joinui.Ui_JoinClient):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setupUi(self)
self.setWindowFlag(QtCore.Qt.FramelessWindowHint)
self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
self.joinbtn.clicked.connect(self.connect_to_meeting)
self.x_btn.clicked.connect(self.btn_close_clicked)
self.minus_btn.clicked.connect(self.btn_minus_clicked)
def mousePressEvent(self, event):
self.start = self.mapToGlobal(event.pos())
self.pressing = True
def mouseMoveEvent(self, event):
if self.pressing:
self.end = self.mapToGlobal(event.pos())
self.movement = self.end - self.start
self.setGeometry(self.mapToGlobal(self.movement).x(),
self.mapToGlobal(self.movement).y(),
self.width(),
self.height())
self.start = self.end
def mouseReleaseEvent(self, QMouseEvent):
self.pressing = False
def btn_close_clicked(self):
self.close()
def btn_minus_clicked(self):
self.showMinimized()
def connect_to_meeting(self):
print(self.username_edit.text())
print(self.code_edit.text())
self.meetClient = CallClient(self.code_edit.text(), self.username_edit.text())
self.meetClient.show()
self.close()
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
main_client = JoinClient()
main_client.show()
sys.exit(app.exec_())
network.py
import socket
import pickle
class Network:
def __init__(self, data: dict):
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server = "192.168.1.38"
self.port = 5555
self.addr = (self.server, self.port)
self.connect(data)
def connect(self, data: dict):
try:
self.client.connect(self.addr)
self.client.send(pickle.dumps(data))
print('connected :D')
except:
pass
def send(self, data):
try:
self.client.send(pickle.dumps(data))
return pickle.loads(self.client.recv(2048*500))
except socket.error as e:
print(e)
server.py
import socket
import threading
from models import Meeting
import pickle
server = "192.168.1.38"
port = 5555
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.bind((server, port))
except socket.error as e:
str(e)
s.listen(2)
print("Waiting for a connection, Server Started")
meetings = []
def threaded_client(conn):
initials = pickle.loads(conn.recv(2048))
currentMeeting = None
currentMeetingIndex = 0
p = 'p1'
for meeting in meetings:
if initials['code'] == meeting.code:
currentMeeting = meeting
p = 'p2'
currentMeetingIndex = meetings.index(currentMeeting)
meetings[currentMeetingIndex].P2 = {'name': initials['name'], 'video_frame': None, 'audio': None}
if not currentMeeting:
currentMeeting = Meeting({'name': initials['name'], 'video_frame': None, 'audio': None}, {'name': None, 'video_frame': None, 'audio': None}, initials['code'])
meetings.append(currentMeeting)
currentMeetingIndex = meetings.index(currentMeeting)
reply = ""
while True:
try:
data = pickle.loads(conn.recv(2048*500))
if not data:
print("Disconnected")
if p == 'p1':
meetings[currentMeetingIndex].P1 = {'name': None, 'video_frame': None, 'audio': None}
else:
meetings[currentMeetingIndex].P2 = {'name': None, 'video_frame': None, 'audio': None}
break
else:
if p == 'p1':
meetings[currentMeetingIndex].P1['video_frame'] = data['video_frame']
meetings[currentMeetingIndex].P1['audio'] = data['audio']
reply = meetings[currentMeetingIndex].P2
else:
meetings[currentMeetingIndex].P2['video_frame'] = data['video_frame']
meetings[currentMeetingIndex].P2['audio'] = data['audio']
reply = meetings[currentMeetingIndex].P1
print("Received: ", data)
print("Sending : ", reply)
conn.sendall(pickle.dumps(reply))
except:
break
if not currentMeeting.P1['name'] and not currentMeeting.P2['name']:
meetings.remove(currentMeeting)
print('meet ended')
print("Lost connection")
print(meetings)
conn.close()
while True:
conn, addr = s.accept()
print("Connected to:", addr)
if conn:
new_thread = threading.Thread(target=threaded_client, args=(conn,))
new_thread.start()
One of the inconvenient things about TCP is that it is a streaming protocol, not a packet protocol. The bytes get transferred eventually, but it doesn't honor your packet boundaries. If you send a 2048-byte chunk and a 1024-byte chunk, depending on network traffic you might receive 500 bytes, then 1000 bytes, then 600, then the last 972. You cannot assume that you are receiving a complete pickle, nor that you are receiving only one -- they could be combined. You must send some kind of header to allow the other end to reconstruct the packets.
Im trying to display serial data in a simple gui. The serial data is dynamic (temperature sensor).
This is the code which I wrote for the GUI in tkinter, but its throwing error for line number 9.
from time import sleep
import threading
import serial
from tkinter import *
serialdata = []
data = True
class SensorThread(threading.Thread):
def run(self):
seri_=serial.Serial('/dev/ttyACM0', 9600)
try:
i = 0
while True:
serialdata.append(seri_.readline())
i += 1
sleep(1)
except KeyboardInterrupt:
exit()
class Gui(object):
def __init__(self):
self.root = Tk()
self.lbl = Label(self.root, text="")
self.updateGUI()
self.readSensor()
def run(self):
self.lbl.pack()
self.lbl.after(1000, self.updateGUI)
self.root.mainloop()
def updateGUI(self):
msg = "Data is True" if data else "Data is False"
self.lbl["text"] = msg
self.root.update()
self.lbl.after(1000, self.updateGUI)
def readSensor(self):
self.lbl["text"] = serialdata[-1]
self.root.update()
self.root.after(527, self.readSensor)
if __name__ == "__main__":
SensorThread().start()
Gui().run()
While running this code Im getting this error. Can anyone please help resolve it :-
Traceback (most recent call last):
File "ts.py", line 39, in <module> Gui().run() File "ts.py", line 23, in __init__ self.readSensor() File "ts.py", line 34, in readSensor self.lbl["text"] = serialdata[0] IndexError: list index out of range
The following example will make is work. Just added a try except IndexError to make sure serialdata is not empty. I replaced the SensorThread with a function that adds a random int between 0 and 100 to the serialdata every one second.
import random
from time import sleep
import threading
from tkinter import *
serialdata = []
data = True
class SensorThread(threading.Thread):
def run(self):
while True:
sleep(1)
serialdata.append(random.randint(0, 100))
class Gui(object):
def __init__(self):
self.root = Tk()
self.lbl = Label(self.root, text="")
self.updateGUI()
self.readSensor()
def run(self):
self.lbl.pack()
self.lbl.after(1000, self.updateGUI)
self.root.mainloop()
def updateGUI(self):
msg = "Data is True" if data else "Data is False"
self.lbl["text"] = msg
self.root.update()
self.lbl.after(1000, self.updateGUI)
def readSensor(self):
try:
self.lbl["text"] = serialdata[-1]
except IndexError:
pass
self.root.update()
self.root.after(527, self.readSensor)
if __name__ == "__main__":
SensorThread().start()
Gui().run()
Lately I have been working on my python chat project, the server works well but when I use the threading model to run the gui of the client and the select I have a problem with it.
I am able to send data to the server and the server returns the data to the clients but the clients can't print the data.
This is the code of the client :
import socket
import select
from Tkinter import *
import thread
class client(object):
def __init__(self):
self.client_socket = socket.socket()
self.messages =[]
def connect(self):
self.client_socket.connect(('127.0.0.1', 1234))
def getgui(self, window):
self.root = window
def run(self):
while True:
self.rlist, self.wlist, self.xlist = select.select([self.client_socket], [self.client_socket], [])
for current_socket in self.rlist:
data = current_socket.recv(1024)
self.root.print_on_list(data)
def send_to_server(self, word):
self.client_socket.send(word)
class rootgui():
def __init__(self,client_socket):
self.client_socket = client_socket
self.root = Tk()
self.root.geometry('600x700')
self.root.minsize(600, 700)
self.root.maxsize(600, 700)
self.root.title('chat')
self.frame = Frame(self.root)
self.frame.pack()
self.scrollbar = Scrollbar(self.frame)
self.scrollbar.pack(side = RIGHT, fill = Y)
self.chatlist = Listbox(self.frame, yscrollcommand = self.scrollbar.set, width = 80, height = 25 )
self.chatlist.pack(side = LEFT)
self.leftframe = Frame(self.root)
self.leftframe.pack(side = LEFT)
self.send_button = Button(self.leftframe, text = 'send', bg = 'green', padx = 60, pady = 70, command = self.send)
self.send_button.pack()
self.rightframe = Frame(self.root)
self.rightframe.pack(side = RIGHT)
self.text = StringVar()
self.input_box = Entry(self.rightframe, width =55, textvariable = self.text )
self.input_box.pack()
self.scrollbar.config(command = self.chatlist.yview)
def mainloop(self):
self.root.mainloop()
def send(self):
t = self.text.get()
self.client_socket.send_to_server(t)
return
def print_on_list(self, data):
self.chatlist.insert(END, data+'\r\n')
def main():
client_socket = client()
client_socket.connect()
window = rootgui(client_socket)
client_socket.getgui(window)
thread.start_new_thread(window.mainloop())
thread.start_new_thread(client_socket.run())
if __name__ == '__main__':
main()
This is the code of the server:
import socket
import select
class server(object):
''' init function '''
def __init__(self):
self.server_socket = socket.socket()
self.open_client_sockets = []
'''this function send a message to all of the connected clients'''
def send_messages(self, message):
for client_socket in self.open_client_sockets:
client_socket.send(message)
''' this function get a port , it bind the server socket and set the listen to 5 sockets '''
def connection(self):
self.server_socket.bind(('0.0.0.0', 1234))
self.server_socket.listen(5)
''' this function use the select library and read / write from / to the client socket '''
def run(self):
while True:
self.rlist, self.wlist, self.xlist = select.select([self.server_socket]+self.open_client_sockets, self.open_client_sockets, [])
for current_socket in self.rlist:
if current_socket is self.server_socket:
(new_socket, address) = self.server_socket.accept()
self.open_client_sockets.append(new_socket)
print 'new member : ' + str(address)
else:
try:
data = current_socket.recv(1024)
self.send_messages(data)
break
except socket.error:
self.open_client_sockets.remove(current_socket)
print 'Connection with client closed.'
if __name__ == '__main__':
server_socket = server()
server_socket.connection()
server_socket.run()