Python 手把手实现远程控制桌面
本项目旨在让大家理解远控软件的原理,通过远控桌面可以实现远程控制我们的电脑,更好更方便的管理电脑。文末将给出初始版的完整代码,需要使用到的其他工具也会有所说明。最终实现的效果就是只要用户点击了客户端的程序运行,我们就可以在服务端对其进行控制。效果如下:左边是客服端程序运行了,然后我们就可以在左边的另一台电脑上打开服务端程序进行控制,可以看到左边的屏幕图像也已经显示在了右边的电脑上。完整代码见文末!
2import socket
3import threading
4import cv2
5import numpy as np
6from PIL import ImageGrab
7from pynput.mouse import Button,Controller
2m = Controller()
3def recvlink(client):
4 while True:
5 msg=client.recv(1024)
6 msg=msg.decode('utf-8')
7 print(msg)
8 key = msg.split(',')
9 xp = int(key[0])
10 yp = int(key[1])
11 m.position = ((xp,yp))
12 m.click(Button.left,1)
2client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
3#设置服务器ip地址,注意应该是服务器的公网ip
4host='服务器的公网ip'
5#设置要发送到的服务器端口,需要在云服务器管理界面打开对应端口的防火墙
6port=设置的端口
7#建立TCP协议连接,这时候服务器就会监听到到连接请求,并开始等待接受client发送的数据
8client.connect((host,port))
9#建立连接后,服务器端会返回连接成功消息
10start_msg=client.recv(1024)
11print(start_msg.decode('utf-8'))
12#开启一个线程用来接受服务器发来的消息
13t=threading.Thread(target=recvlink,args=(client,))
14t.start()
15p = ImageGrab.grab()#获得当前屏幕
16quality = 25 # 图像的质量
17encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), quality]
18while True:
19 im = ImageGrab.grab()
20 imm=cv2.cvtColor(np.array(im), cv2.COLOR_RGB2BGR)#转为opencv的BGR格式
21 imm = cv2.resize(imm, (1535, 863))
22 img_encode = cv2.imencode('.jpg', imm, encode_param)[1]
23 data_encode = np.array(img_encode)
24 str_encode = data_encode.tostring()
25 #print(len(str_encode))
26 #输入要发送的信息
27 sendmsg='kehu'
28 #向服务器发送消息
29 client.send(str_encode)
30 if sendmsg=='quit':
31 break
32#结束时关闭客户端
33client.close()
2import socket
3import threading
4import numpy as np
5import cv2
6import os
2def mouse_click(event, x, y, flags, para):
3 if event == cv2.EVENT_LBUTTONDOWN: # 左边鼠标点击
4 f=open('1.txt','w')
5 f.write(str(x) ',' str(y))
6 f.close()
2 while True:
3 # 接受客户端消息,设置一次最多接受10240字节的数据
4 recv_msg = clientsocket.recv(102400)
5 # 把接收到的东西解码
6 msg = np.fromstring(recv_msg, np.uint8)
7 img_decode = cv2.imdecode(msg, cv2.IMREAD_COLOR)
8 try:
9 s=img_decode.shape
10 img_decode=img_decode
11 temp=img_decode
12 except:
13 img_decode=temp
14 pass
15 cv2.imshow('SERVER', img_decode)
16 cv2.setMouseCallback('SERVER', mouse_click)
17 try:
18 f=open('1.txt')
19 txt=f.read()
20 f.close()
21 reply=txt
22 print(reply)
23 clientsocket.send(reply.encode('utf-8'))
24 os.remove('1.txt')
25 except:
26 pass
27 if cv2.waitKey(1) & 0xFF == ord('q'):
28 break
2 socket_server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
3 host='服务器的本地ip'
4 #设置被监听的端口号,小于1024的端口号不能使用
5 port=设置的端口
6 socket_server.bind((host,port))
7 #设置最大监听数,也就是最多可以同时响应几个客户端请求,一般配合多线程使用
8 socket_server.listen(5)
9 #等待客户端连接,一旦有了连接就立刻向下执行,否则等待
10 #accept()函数会返回一个元组,第一个元素是客户端socket对象,第二个元素是客户端地址(ip地址 端口号)
11 clientsocket,addr=socket_server.accept()
12 # 有了客户端连接后之后才能执行以下代码,我们先向客户端发送连接成功消息
13 clientsocket.send('连接成功'.encode('utf-8'))
14 # 和客户端一样开启一个线程接受客户端的信息
15 t=threading.Thread(target=recv_msg,args=(clientsocket,))
16 t.start()
2from PyQt5.QtCore import *
3from PyQt5.QtGui import QPalette, QBrush, QPixmap
4import os
5import socket
6import threading
7import cv2
8import numpy as np
9from PIL import ImageGrab
10from pynput.mouse import Button,Controller
11import time
2def mouse_click(event, x, y, flags, para):
3 if event == cv2.EVENT_LBUTTONDOWN: # 左边鼠标点击
4 print( x, y)
5 m.position = (x, y)
6 time.sleep(0.1)
7 m.click(Button.left, 1)
2 super(Ui_MainWindow, self).__init__(parent)
3 # self.face_recong = face.Recognition()
4 self.timer_camera = QtCore.QTimer()
5 self.cap = cv2.VideoCapture()
6 self.CAM_NUM = 0
7 self.set_ui()
8 self.slot_init()
9 self.__flag_work = 0
10 self.x = 0
11 self.count = 0
2 self.__layout_main = QtWidgets.QHBoxLayout()
3 self.__layout_fun_button = QtWidgets.QVBoxLayout()
4 self.__layout_data_show = QtWidgets.QVBoxLayout()
5 self.button_open_camera = QtWidgets.QPushButton(u'远程桌面')
6 self.button_close = QtWidgets.QPushButton(u'退出')
7 # Button 的颜色修改
8 button_color = [self.button_open_camera, self.button_close]
9 for i in range(2):
10 button_color[i].setStyleSheet('QPushButton{color:black}'
11 'QPushButton:hover{color:red}'
12 'QPushButton{background-color:rgb(78,255,255)}'
13 'QPushButton{border:2px}'
14 'QPushButton{border-radius:10px}'
15 'QPushButton{padding:2px 4px}')
16 self.button_open_camera.setMinimumHeight(50)
17 self.button_close.setMinimumHeight(50)
18 # move()方法移动窗口在屏幕上的位置到x = 300,y = 300坐标。
19 self.move(500, 500)
20 # 信息显示
21 self.label_show_camera = QtWidgets.QLabel()
22 self.label_move = QtWidgets.QLabel()
23 self.label_move.setFixedSize(100, 100)
24 self.label_show_camera.setFixedSize(1530,863)
25 self.label_show_camera.setAutoFillBackground(False)
26 self.__layout_fun_button.addWidget(self.button_open_camera)
27 self.__layout_fun_button.addWidget(self.button_close)
28 self.__layout_fun_button.addWidget(self.label_move)
29 self.__layout_main.addLayout(self.__layout_fun_button)
30 self.__layout_main.addWidget(self.label_show_camera)
31 self.setLayout(self.__layout_main)
32 self.label_move.raise_()
33 self.setWindowTitle(u'远控桌面GUI')
34 '''
35 # 设置背景图片
36 palette1 = QPalette()
37 palette1.setBrush(self.backgroundRole(), QBrush(QPixmap('background.jpg')))
38 self.setPalette(palette1)
39 '''
2 if event.buttons() & QtCore.Qt.LeftButton:
3 x = event.x()-120
4 y = event.y()-10
5 text = 'x: {0},y: {1}'.format(x,y)
6 if x>=0 and y>=0:
7 m.position = (x, y)
8 time.sleep(0.1)
9 m.click(Button.left, 1)
10 print(text)
2 self.button_open_camera.clicked.connect(self.button_open_camera_click)
3 self.timer_camera.timeout.connect(self.show_camera)
4 self.button_close.clicked.connect(self.close)
2 if self.timer_camera.isActive() == False:
3 self.timer_camera.start(30)
4 self.button_open_camera.setText(u'关闭')
5 else:
6 self.timer_camera.stop()
7 self.cap.release()
8 self.label_show_camera.clear()
9 self.button_open_camera.setText(u'远程桌面')
2 im = ImageGrab.grab()
3 imm = cv2.cvtColor(np.array(im), cv2.COLOR_RGB2BGR) # 转为opencv的BGR格式
4 #imm = cv2.resize(imm, (1535, 863))
5 self.image = imm
6 # face = self.face_detect.align(self.image)
7 # if face:
8 # pass
9 show =cv2.resize(self.image, (1536,863))
10 show = cv2.cvtColor(show, cv2.COLOR_BGR2RGB)
11 print(show.shape[1], show.shape[0])
12 # show.shape[1] = 640, show.shape[0] = 480
13 showImage = QtGui.QImage(show.data, show.shape[1], show.shape[0], QtGui.QImage.Format_RGB888)
14 self.label_show_camera.setPixmap(QtGui.QPixmap.fromImage(showImage))
15 #cv2.setMouseCallback(showImage, mouse_click)
16 # self.x = 1
17 # self.label_move.move(self.x,100)
18 # if self.x ==320:
19 # self.label_show_camera.raise_()
20def closeEvent(self, event):
21 ok = QtWidgets.QPushButton()
22 cacel = QtWidgets.QPushButton()
23 msg = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Warning, u'关闭', u'是否关闭!')
24 msg.addButton(ok, QtWidgets.QMessageBox.ActionRole)
25 msg.addButton(cacel, QtWidgets.QMessageBox.RejectRole)
26 ok.setText(u'确定')
27 cacel.setText(u'取消')
28 # msg.setDetailedText('sdfsdff')
29 if msg.exec_() == QtWidgets.QMessageBox.RejectRole:
30 event.ignore()
31 else:
32 # self.socket_client.send_command(self.socket_client.current_user_command)
33 if self.cap.isOpened():
34 self.cap.release()
35 if self.timer_camera.isActive():
36 self.timer_camera.stop()
37 event.accept()
赞 (0)