我正在做一个带有python套接字的客户端服务器程序,以通过Stream中的TCP视频协议从客户端传输到服务器。此过程在以Tkinter按钮开头的辅助线程内部。问题是按钮保持按下状态,并且在画布上显示图像时,如果它们没有加载,则不会出现明显的变化。我一直在阅读,显然您必须使用一个名为“ Queue”的库,但是它不会在我的代码中实现。
# Import libraries
import threading
import SocketServer
import socket
import PIL.Image, PIL.ImageTk
import cv2
import numpy as np
import math
from Tkinter import*
# Config vars
server_ip = '192.168.1.36'
server_port = 8000
image_fps = 24
title = "Proyect 1"
def init_server (server):
server.init_server(server_ip,server_port)
#-------root and frame-----------#
root = Tk()
root.title(title)
myFrame = Frame(root,width="600",height="600")
root.resizable(False, False)
myFrame.pack()
#------------Labels--------------#
lTitle = Label(myFrame,text="Proyect 1.0",fg="gray")
lTitle.grid(row=0, column= 0, pady= 10, padx = 10)
#------------canvas--------------#
canvas = Canvas(myFrame,bg="gray",width=400, height=400)
canvas.grid(row=2,column=0, pady=0, padx=10)
#----------Main loop------------#
def setFrame (frame):
photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(frame))
canvas.create_image(0, 0, image = photo, anchor = NW)
# Class to handle the jpeg video stream received from client
class VideoStreamHandler(SocketServer.StreamRequestHandler):
def handle(self):
stream_bytes = b' '
# stream video frames one by one
try:
while True:
stream_bytes += self.rfile.read(1024)
first = stream_bytes.find(b'\xff\xd8')
last = stream_bytes.find(b'\xff\xd9')
if first != -1 and last != -1:
jpg = stream_bytes[first:last+2]
stream_bytes = stream_bytes[last+2:]
#gray = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8), cv2.IMREAD_GRAYSCALE)
image = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8), cv2.IMREAD_UNCHANGED)
# lower half of the image
#half_gray = gray[120:240, :]
# Mostramos imagenes
setFrame(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
cv2.imshow('mlp_image', image)
# reshape image
#image_array = half_gray.reshape(1, 38400).astype(np.float32)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
finally:
print( 'Connection closed on videostream thread' )
# Class to handle the different threads
class ThreadServer():
# Server thread to handle the video
def server_thread(self,host, port):
server = SocketServer.TCPServer((host, port),VideoStreamHandler)
server.serve_forever()
def init_server(self, host, port):
print( '+ Starting videostream server in ' + str( host ) + ':' + str( port ) )
video_thread = threading.Thread(target=self.server_thread(host,port))
video_thread.start()
#--------ThreadServer------------#
server = None
server = ThreadServer()
#------------Server widgets-------#
bStartServer = Button(myFrame, text="Start server", command=lambda:init_server(server))
bStartServer.grid(row=3,column=0, pady= 10)
#-----------main loop--------------#
root.mainloop()