python socket编程7 - 使用PyQt6 开发UI界面新增实现UDP server和client单机通讯的例子

在第五篇中,简单实现了命令行下的 TCP/UDP server和client的单机通讯。
在第六篇中,实现了PyQt6开发界面,TCP协议实现的单机server和client的通讯功能。
这一篇,在第六篇的基础上,增加了UDP server和client的单机通讯功能。

一、界面

在这里插入图片描述

二、对比命令行代码的封装示意

1、UDP Server 界面实现服务配置和数据提供

在这里插入图片描述

2、UDP Server封装成2个部分:UDPServer和UDPServerSocketReceiveThread

在这里插入图片描述

3、server 完整代码

import socket

from PyQt6.QtCore import QThread, pyqtSignal


class UDPServer:
    def __init__(self, ui, server_ip, server_hostname, server_port):
        self.clientAddr = None
        self.ui = ui  # 主界面
        self.ip = server_ip  # 服务器ip地址
        self.port = server_port  # 服务器端口号
        self.serverName = server_hostname  # 显示名称
        self.is_running = False  # 是否已经启动

        self.socket = None  # socket
        self.socketThread = None  # 新的 socket receive 线程

        self.start()

    def start(self):
        if not self.is_running:
            self.is_running = True
            self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            self.socket.bind((self.ip, self.port))  # 绑定IP与端口
            self.startSocketReceiveThread()

    def startSocketReceiveThread(self):
        self.socketThread = UDPServerSocketReceiveThread(self.socket)
        self.socketThread.receivedClientData.connect(self.show_client_message)
        self.socketThread.clientAddr.connect(self.server_status_trigger)
        self.socketThread.start()

    def send_data_to_client(self, message):
        self.ui.textEdit_3.append(self.serverName + ':' + message)
        self.socket.sendto(message.encode(), self.clientAddr)

    def server_status_trigger(self, clientAddr):
        self.clientAddr = clientAddr

    def show_client_message(self, message):
        self.ui.textEdit_3.append('客户端:' + message)


class UDPServerSocketReceiveThread(QThread):
    receivedClientData: pyqtSignal = pyqtSignal(str)  # 向主线程发送客户端的数据
    clientAddr: pyqtSignal = pyqtSignal(tuple)  # 向主线程发送服务器状态

    def __init__(self, serverSocket):
        super(UDPServerSocketReceiveThread, self).__init__()
        self.serverSocket = serverSocket
        self.clientSocket = None
        self.addr = None
        self.is_running = True

    def run(self):
        self.startReceiveData()

    def startReceiveData(self):
        while self.is_running:
            try:
                message, clientAddress = self.serverSocket.recvfrom(2048)
                self.receivedClientData.emit(message.decode('utf-8'))
                self.clientAddr.emit(clientAddress)
            except ConnectionResetError as reason:
                self.is_running = False
                break


class TCPServer:

    def __init__(self, ui, server_ip, server_hostname, server_port):

        self.ui = ui  # 主界面
        self.ip = server_ip  # 服务器ip地址
        self.port = server_port  # 服务器端口号
        self.serverName = server_hostname  # 显示名称
        self.is_running = False  # 是否已经启动

        self.socket = None  # socket
        self.socketThread = None  # 新的 socket receive 线程

        self.start()

    def start(self):
        if not self.is_running:
            self.is_running = True
            self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.socket.bind((self.ip, self.port))  # 绑定IP与端口
            self.socket.listen(1)  # 设定最大连接数
            self.startSocketReceiveThread()

    def stop(self):
        try:
            if self.is_running:
                self.is_running = False
                if self.socketThread.is_running:
                    self.socketThread.stop()
        except Exception as e:
            print(e)

    def startSocketReceiveThread(self):
        self.socketThread = TCPServerSocketReceiveThread(self.socket)
        self.socketThread.clientConnection.connect(self.socket_client_connect_trigger)
        self.socketThread.receivedClientData.connect(self.show_client_message)
        self.socketThread.serverStatus.connect(self.server_status_trigger)
        self.socketThread.start()

    def server_status_trigger(self, status):
        self.ui.statusbar.showMessage(status)

    def socket_client_connect_trigger(self, state):
        if state == 'connect':
            self.ui.statusbar.showMessage("客户端已经连接。")
        else:
            self.ui.statusbar.showMessage("客户端已经断开。")

    def show_client_message(self, message):
        self.ui.textEdit.append('客户端:' + message)

    def send_message_to_client(self, message):
        if self.is_running:
            self.ui.textEdit.append(self.serverName + ':' + message)
            self.socketThread.send_data_to_client(message)


class TCPServerSocketReceiveThread(QThread):
    clientConnection: pyqtSignal = pyqtSignal(str)  # 向主线程发送连接状态标志
    receivedClientData: pyqtSignal = pyqtSignal(str)  # 向主线程发送接受到客户端的数据
    serverStatus: pyqtSignal = pyqtSignal(str)  # 向主线程发送服务器状态

    def __init__(self, serverSocket):
        super(TCPServerSocketReceiveThread, self).__init__()
        self.serverSocket = serverSocket
        self.clientSocket = None
        self.addr = None
        self.is_running = True

    def run(self):
        self.serverStatus.emit("服务已经启动,等待客户端的连接......")
        self.clientSocket, self.addr = self.serverSocket.accept()  # 接受客户端的连接
        self.emitConnectEvent('connect')  # 发送客户端连接成功通知到主界面
        self.startReceiveData()

    def startReceiveData(self):
        while self.is_running:
            try:
                data = self.clientSocket.recv(1024).decode('utf-8')  # 接受到字符串并按照utf-8编译
                if not data:
                    self.emitConnectEvent('disconnect')  # 发送客户端断开通知到主界面
                    break
                self.sendClientDataToUi(data)
            except ConnectionResetError as reason:
                self.sendClientDataToUi("已经离开对话。")
                self.is_running = False
                self.emitConnectEvent('disconnect')  # 发送客户端断开通知到主界面
                break
        self.clientSocket.close()
        self.serverSocket.close()
        self.serverStatus.emit("服务已经关闭。")

    def send_data_to_client(self, message):
        try:
            self.clientSocket.send(message.encode("utf-8"))
        except Exception as reason:
            print("发送失败,原因:", reason)

    def stop(self):
        if self.is_running:
            self.is_running = False

    def emitConnectEvent(self, state):
        self.clientConnection.emit(state)

    def sendClientDataToUi(self, message):
        self.receivedClientData.emit(message)

4、client 完整代码

import socket
from PyQt6.QtCore import QThread, pyqtSignal


class UDPClient:

    def __init__(self, ui, ip, clientName, port):
        self.ui = ui
        self.ip = ip
        self.hostName = clientName
        self.port = port

        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.socketThread = None
        self.startSocketReceiveThread()

    def send_udp_data(self, sentence):
        self.ui.textEdit_4.append(self.hostName + ":" + sentence)
        self.socket.sendto(sentence.encode(), (self.ip, self.port))

    def startSocketReceiveThread(self):
        self.socketThread = UDPClientSocketReceiveThread(self.socket)
        self.socketThread.receivedServerData.connect(self.show_server_message)
        self.socketThread.start()

    def show_server_message(self, message):
        self.ui.textEdit_4.append('服务端:' + message)


class UDPClientSocketReceiveThread(QThread):
    receivedServerData: pyqtSignal = pyqtSignal(str)  # 向主线程发送接受到客户端的数据

    def __init__(self, clientSocket):
        super(UDPClientSocketReceiveThread, self).__init__()
        self.clientSocket = clientSocket
        self.addr = None
        self.is_running = True

    def run(self):
        self.startReceiveData()

    def startReceiveData(self):
        while self.is_running:
            try:
                message, clientAddress = self.clientSocket.recvfrom(2048)
                self.receivedServerData.emit(message.decode('utf-8'))
            except ConnectionResetError as reason:
                self.is_running = False
                break


class TCPClient:

    def __init__(self, ui, ip, clientName, port):
        self.ui = ui
        self.ip = ip
        self.hostName = clientName
        self.port = port

        self.socket = None
        self.socketThread = None
        self.connect_server()

    def connect_server(self):
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socketThread = TCPClientSocketReceiveThread(self.socket)
        self.socketThread.receivedServerData.connect(self.update_ui_chat_content)
        if self.connect_success(self.ip, self.port):
            self.socketThread.start()

    def update_ui_chat_content(self, serverMessage):
        self.ui.textEdit_2.append("服务端:" + serverMessage)

    def stop(self):
        self.socketThread.stop()

    def send_data(self, sentence):
        self.ui.textEdit_2.append(self.hostName + ":" + sentence)
        self.socket.send(sentence.encode())

    def connect_success(self, ip, port):
        try:
            self.socket.connect((ip, port))
            return True
        except Exception as reason:
            print(reason)
            return False


class TCPClientSocketReceiveThread(QThread):
    receivedServerData: pyqtSignal = pyqtSignal(str)  # 向主线程发送接受到客户端的数据

    def __init__(self, clientSocket):
        super(TCPClientSocketReceiveThread, self).__init__()
        self.clientSocket = clientSocket
        self.is_running = True

    def stop(self):
        self.is_running = False
        self.clientSocket.close()

    def run(self):
        while self.is_running:
            try:
                msg = self.clientSocket.recv(1024).decode("utf-8")  # 接受服务端消息
                if not msg:
                    break
                self.receivedServerData.emit(msg)
            except Exception as reason:
                print(reason)
                break
        self.stop()
        self.receivedServerData.emit("已经与服务端断开。")

5、主控逻辑代码

"""
主窗口模块
"""
from PyQt6 import QtWidgets
from .server import TCPServer, UDPServer
from .client import TCPClient, UDPClient
from ui.ui_Main import Ui_MainWindow


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    """
        主窗口初始化
    """

    def __init__(self):
        super(MainWindow, self).__init__()

        self.setupUi(self)
        self.show()

        self.pushButton.clicked.connect(self.tcp_server_start)
        self.pushButton_2.clicked.connect(self.tcp_server_stop)
        self.pushButton_4.clicked.connect(self.tcp_server_send_data)

        self.pushButton_5.clicked.connect(self.client_connect_server)
        self.pushButton_6.clicked.connect(self.client_disconnect_server)
        self.pushButton_7.clicked.connect(self.client_send_data)

        self.pushButton_8.clicked.connect(self.udp_server_start)
        self.pushButton_12.clicked.connect(self.send_udp_data_to_client)
        self.pushButton_13.clicked.connect(self.send_udp_data_to_server)

        self.tcpServer = None
        self.tcpClient = None

        self.udpServer = None
        self.udpClient = None

    def send_udp_data_to_client(self):
        self.udpServer.send_data_to_client(self.lineEdit_11.text())

    def send_udp_data_to_server(self):
        if self.udpClient is None:
            server_ip = self.lineEdit_9.text()
            server_port = int(self.lineEdit_10.text())
            client_name = '客户端'
            self.udpClient = UDPClient(self, server_ip, client_name, server_port)
        self.udpClient.send_udp_data(self.lineEdit_12.text())

    def client_connect_server(self):
        server_ip = self.lineEdit_5.text()
        server_port = int(self.lineEdit_6.text())
        client_name = '客户端'
        self.tcpClient = TCPClient(self, server_ip, client_name, server_port)

    def client_disconnect_server(self):
        self.tcpClient.stop()

    def client_send_data(self):
        message = self.lineEdit_7.text()
        self.tcpClient.send_data(message)

    def tcp_server_start(self):
        server_ip = self.lineEdit.text()
        server_port = int(self.lineEdit_2.text())
        server_name = '服务器'
        self.tcpServer = TCPServer(self, server_ip, server_name, server_port)

    def tcp_server_stop(self):
        self.tcpServer.stop()

    def tcp_server_send_data(self):
        message = self.lineEdit_4.text()
        self.tcpServer.send_message_to_client(message)

    def udp_server_start(self):
        server_ip = self.lineEdit_3.text()
        server_port = int(self.lineEdit_8.text())
        server_name = '服务器'
        self.udpServer = UDPServer(self, server_ip, server_name, server_port)

6、Ui完整代码

# Form implementation generated from reading ui file 'D:\projects\python-projects\dhcp-server\ui\Main.ui'
#
# Created by: PyQt6 UI code generator 6.4.2
#
# WARNING: Any manual changes made to this file will be lost when pyuic6 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt6 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(934, 600)
        self.centralwidget = QtWidgets.QWidget(parent=MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.tabWidget = QtWidgets.QTabWidget(parent=self.centralwidget)
        self.tabWidget.setObjectName("tabWidget")
        self.tab = QtWidgets.QWidget()
        self.tab.setObjectName("tab")
        self.horizontalLayout_10 = QtWidgets.QHBoxLayout(self.tab)
        self.horizontalLayout_10.setObjectName("horizontalLayout_10")
        self.verticalLayout_5 = QtWidgets.QVBoxLayout()
        self.verticalLayout_5.setObjectName("verticalLayout_5")
        self.groupBox = QtWidgets.QGroupBox(parent=self.tab)
        font = QtGui.QFont()
        font.setPointSize(11)
        self.groupBox.setFont(font)
        self.groupBox.setObjectName("groupBox")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.groupBox)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.label = QtWidgets.QLabel(parent=self.groupBox)
        self.label.setObjectName("label")
        self.horizontalLayout_2.addWidget(self.label)
        self.lineEdit = QtWidgets.QLineEdit(parent=self.groupBox)
        self.lineEdit.setObjectName("lineEdit")
        self.horizontalLayout_2.addWidget(self.lineEdit)
        self.pushButton_3 = QtWidgets.QPushButton(parent=self.groupBox)
        self.pushButton_3.setObjectName("pushButton_3")
        self.horizontalLayout_2.addWidget(self.pushButton_3)
        self.verticalLayout_2.addLayout(self.horizontalLayout_2)
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.label_2 = QtWidgets.QLabel(parent=self.groupBox)
        self.label_2.setObjectName("label_2")
        self.horizontalLayout_3.addWidget(self.label_2)
        self.lineEdit_2 = QtWidgets.QLineEdit(parent=self.groupBox)
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.horizontalLayout_3.addWidget(self.lineEdit_2)
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout_3.addItem(spacerItem)
        self.horizontalLayout_3.setStretch(2, 1)
        self.verticalLayout_2.addLayout(self.horizontalLayout_3)
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        self.verticalLayout_2.addLayout(self.horizontalLayout_4)
        self.verticalLayout_5.addWidget(self.groupBox)
        self.verticalLayout_4 = QtWidgets.QVBoxLayout()
        self.verticalLayout_4.setObjectName("verticalLayout_4")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout.addItem(spacerItem1)
        self.pushButton = QtWidgets.QPushButton(parent=self.tab)
        font = QtGui.QFont()
        font.setPointSize(11)
        self.pushButton.setFont(font)
        self.pushButton.setObjectName("pushButton")
        self.horizontalLayout.addWidget(self.pushButton)
        spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout.addItem(spacerItem2)
        self.pushButton_2 = QtWidgets.QPushButton(parent=self.tab)
        font = QtGui.QFont()
        font.setPointSize(11)
        self.pushButton_2.setFont(font)
        self.pushButton_2.setObjectName("pushButton_2")
        self.horizontalLayout.addWidget(self.pushButton_2)
        spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout.addItem(spacerItem3)
        self.verticalLayout_4.addLayout(self.horizontalLayout)
        self.verticalLayout_3 = QtWidgets.QVBoxLayout()
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.textEdit = QtWidgets.QTextEdit(parent=self.tab)
        self.textEdit.setObjectName("textEdit")
        self.verticalLayout_3.addWidget(self.textEdit)
        self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_5.setObjectName("horizontalLayout_5")
        self.lineEdit_4 = QtWidgets.QLineEdit(parent=self.tab)
        self.lineEdit_4.setObjectName("lineEdit_4")
        self.horizontalLayout_5.addWidget(self.lineEdit_4)
        self.pushButton_4 = QtWidgets.QPushButton(parent=self.tab)
        font = QtGui.QFont()
        font.setPointSize(11)
        self.pushButton_4.setFont(font)
        self.pushButton_4.setObjectName("pushButton_4")
        self.horizontalLayout_5.addWidget(self.pushButton_4)
        self.verticalLayout_3.addLayout(self.horizontalLayout_5)
        self.verticalLayout_4.addLayout(self.verticalLayout_3)
        self.verticalLayout_5.addLayout(self.verticalLayout_4)
        self.horizontalLayout_10.addLayout(self.verticalLayout_5)
        self.verticalLayout_8 = QtWidgets.QVBoxLayout()
        self.verticalLayout_8.setObjectName("verticalLayout_8")
        self.groupBox_2 = QtWidgets.QGroupBox(parent=self.tab)
        font = QtGui.QFont()
        font.setPointSize(11)
        self.groupBox_2.setFont(font)
        self.groupBox_2.setObjectName("groupBox_2")
        self.verticalLayout_9 = QtWidgets.QVBoxLayout(self.groupBox_2)
        self.verticalLayout_9.setObjectName("verticalLayout_9")
        self.horizontalLayout_6 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_6.setObjectName("horizontalLayout_6")
        self.label_4 = QtWidgets.QLabel(parent=self.groupBox_2)
        self.label_4.setObjectName("label_4")
        self.horizontalLayout_6.addWidget(self.label_4)
        self.lineEdit_5 = QtWidgets.QLineEdit(parent=self.groupBox_2)
        self.lineEdit_5.setObjectName("lineEdit_5")
        self.horizontalLayout_6.addWidget(self.lineEdit_5)
        self.verticalLayout_9.addLayout(self.horizontalLayout_6)
        self.horizontalLayout_7 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_7.setObjectName("horizontalLayout_7")
        self.label_5 = QtWidgets.QLabel(parent=self.groupBox_2)
        self.label_5.setObjectName("label_5")
        self.horizontalLayout_7.addWidget(self.label_5)
        self.lineEdit_6 = QtWidgets.QLineEdit(parent=self.groupBox_2)
        self.lineEdit_6.setObjectName("lineEdit_6")
        self.horizontalLayout_7.addWidget(self.lineEdit_6)
        self.verticalLayout_9.addLayout(self.horizontalLayout_7)
        self.verticalLayout_8.addWidget(self.groupBox_2)
        self.verticalLayout_7 = QtWidgets.QVBoxLayout()
        self.verticalLayout_7.setObjectName("verticalLayout_7")
        self.horizontalLayout_8 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_8.setObjectName("horizontalLayout_8")
        spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout_8.addItem(spacerItem4)
        self.pushButton_5 = QtWidgets.QPushButton(parent=self.tab)
        font = QtGui.QFont()
        font.setPointSize(11)
        self.pushButton_5.setFont(font)
        self.pushButton_5.setObjectName("pushButton_5")
        self.horizontalLayout_8.addWidget(self.pushButton_5)
        spacerItem5 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout_8.addItem(spacerItem5)
        self.pushButton_6 = QtWidgets.QPushButton(parent=self.tab)
        font = QtGui.QFont()
        font.setPointSize(11)
        self.pushButton_6.setFont(font)
        self.pushButton_6.setObjectName("pushButton_6")
        self.horizontalLayout_8.addWidget(self.pushButton_6)
        spacerItem6 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout_8.addItem(spacerItem6)
        self.verticalLayout_7.addLayout(self.horizontalLayout_8)
        self.verticalLayout_6 = QtWidgets.QVBoxLayout()
        self.verticalLayout_6.setObjectName("verticalLayout_6")
        self.textEdit_2 = QtWidgets.QTextEdit(parent=self.tab)
        self.textEdit_2.setObjectName("textEdit_2")
        self.verticalLayout_6.addWidget(self.textEdit_2)
        self.horizontalLayout_9 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_9.setObjectName("horizontalLayout_9")
        self.lineEdit_7 = QtWidgets.QLineEdit(parent=self.tab)
        self.lineEdit_7.setObjectName("lineEdit_7")
        self.horizontalLayout_9.addWidget(self.lineEdit_7)
        self.pushButton_7 = QtWidgets.QPushButton(parent=self.tab)
        font = QtGui.QFont()
        font.setPointSize(11)
        self.pushButton_7.setFont(font)
        self.pushButton_7.setObjectName("pushButton_7")
        self.horizontalLayout_9.addWidget(self.pushButton_7)
        self.verticalLayout_6.addLayout(self.horizontalLayout_9)
        self.verticalLayout_7.addLayout(self.verticalLayout_6)
        self.verticalLayout_8.addLayout(self.verticalLayout_7)
        self.horizontalLayout_10.addLayout(self.verticalLayout_8)
        self.tabWidget.addTab(self.tab, "")
        self.tab_2 = QtWidgets.QWidget()
        self.tab_2.setObjectName("tab_2")
        self.horizontalLayout_19 = QtWidgets.QHBoxLayout(self.tab_2)
        self.horizontalLayout_19.setObjectName("horizontalLayout_19")
        self.verticalLayout_16 = QtWidgets.QVBoxLayout()
        self.verticalLayout_16.setObjectName("verticalLayout_16")
        self.verticalLayout_13 = QtWidgets.QVBoxLayout()
        self.verticalLayout_13.setObjectName("verticalLayout_13")
        self.groupBox_3 = QtWidgets.QGroupBox(parent=self.tab_2)
        font = QtGui.QFont()
        font.setPointSize(11)
        self.groupBox_3.setFont(font)
        self.groupBox_3.setObjectName("groupBox_3")
        self.verticalLayout_11 = QtWidgets.QVBoxLayout(self.groupBox_3)
        self.verticalLayout_11.setObjectName("verticalLayout_11")
        self.horizontalLayout_11 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_11.setContentsMargins(-1, -1, 5, -1)
        self.horizontalLayout_11.setObjectName("horizontalLayout_11")
        self.label_3 = QtWidgets.QLabel(parent=self.groupBox_3)
        self.label_3.setObjectName("label_3")
        self.horizontalLayout_11.addWidget(self.label_3)
        self.lineEdit_3 = QtWidgets.QLineEdit(parent=self.groupBox_3)
        self.lineEdit_3.setObjectName("lineEdit_3")
        self.horizontalLayout_11.addWidget(self.lineEdit_3)
        self.verticalLayout_11.addLayout(self.horizontalLayout_11)
        self.horizontalLayout_12 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_12.setContentsMargins(-1, -1, 5, -1)
        self.horizontalLayout_12.setObjectName("horizontalLayout_12")
        self.label_6 = QtWidgets.QLabel(parent=self.groupBox_3)
        self.label_6.setObjectName("label_6")
        self.horizontalLayout_12.addWidget(self.label_6)
        self.lineEdit_8 = QtWidgets.QLineEdit(parent=self.groupBox_3)
        self.lineEdit_8.setObjectName("lineEdit_8")
        self.horizontalLayout_12.addWidget(self.lineEdit_8)
        self.verticalLayout_11.addLayout(self.horizontalLayout_12)
        self.verticalLayout_13.addWidget(self.groupBox_3)
        self.horizontalLayout_15 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_15.setObjectName("horizontalLayout_15")
        spacerItem7 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout_15.addItem(spacerItem7)
        self.pushButton_8 = QtWidgets.QPushButton(parent=self.tab_2)
        font = QtGui.QFont()
        font.setPointSize(11)
        self.pushButton_8.setFont(font)
        self.pushButton_8.setObjectName("pushButton_8")
        self.horizontalLayout_15.addWidget(self.pushButton_8)
        spacerItem8 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout_15.addItem(spacerItem8)
        spacerItem9 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout_15.addItem(spacerItem9)
        self.verticalLayout_13.addLayout(self.horizontalLayout_15)
        self.verticalLayout_16.addLayout(self.verticalLayout_13)
        self.verticalLayout_15 = QtWidgets.QVBoxLayout()
        self.verticalLayout_15.setObjectName("verticalLayout_15")
        self.textEdit_3 = QtWidgets.QTextEdit(parent=self.tab_2)
        self.textEdit_3.setObjectName("textEdit_3")
        self.verticalLayout_15.addWidget(self.textEdit_3)
        self.horizontalLayout_17 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_17.setObjectName("horizontalLayout_17")
        self.lineEdit_11 = QtWidgets.QLineEdit(parent=self.tab_2)
        self.lineEdit_11.setObjectName("lineEdit_11")
        self.horizontalLayout_17.addWidget(self.lineEdit_11)
        self.pushButton_12 = QtWidgets.QPushButton(parent=self.tab_2)
        font = QtGui.QFont()
        font.setPointSize(11)
        self.pushButton_12.setFont(font)
        self.pushButton_12.setObjectName("pushButton_12")
        self.horizontalLayout_17.addWidget(self.pushButton_12)
        self.verticalLayout_15.addLayout(self.horizontalLayout_17)
        self.verticalLayout_16.addLayout(self.verticalLayout_15)
        self.horizontalLayout_19.addLayout(self.verticalLayout_16)
        self.verticalLayout_17 = QtWidgets.QVBoxLayout()
        self.verticalLayout_17.setObjectName("verticalLayout_17")
        self.verticalLayout_12 = QtWidgets.QVBoxLayout()
        self.verticalLayout_12.setObjectName("verticalLayout_12")
        self.groupBox_4 = QtWidgets.QGroupBox(parent=self.tab_2)
        font = QtGui.QFont()
        font.setPointSize(11)
        self.groupBox_4.setFont(font)
        self.groupBox_4.setObjectName("groupBox_4")
        self.verticalLayout_10 = QtWidgets.QVBoxLayout(self.groupBox_4)
        self.verticalLayout_10.setObjectName("verticalLayout_10")
        self.horizontalLayout_13 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_13.setObjectName("horizontalLayout_13")
        self.label_7 = QtWidgets.QLabel(parent=self.groupBox_4)
        self.label_7.setObjectName("label_7")
        self.horizontalLayout_13.addWidget(self.label_7)
        self.lineEdit_9 = QtWidgets.QLineEdit(parent=self.groupBox_4)
        self.lineEdit_9.setObjectName("lineEdit_9")
        self.horizontalLayout_13.addWidget(self.lineEdit_9)
        self.verticalLayout_10.addLayout(self.horizontalLayout_13)
        self.horizontalLayout_14 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_14.setObjectName("horizontalLayout_14")
        self.label_8 = QtWidgets.QLabel(parent=self.groupBox_4)
        self.label_8.setObjectName("label_8")
        self.horizontalLayout_14.addWidget(self.label_8)
        self.lineEdit_10 = QtWidgets.QLineEdit(parent=self.groupBox_4)
        self.lineEdit_10.setObjectName("lineEdit_10")
        self.horizontalLayout_14.addWidget(self.lineEdit_10)
        self.verticalLayout_10.addLayout(self.horizontalLayout_14)
        self.verticalLayout_12.addWidget(self.groupBox_4)
        self.horizontalLayout_16 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_16.setObjectName("horizontalLayout_16")
        spacerItem10 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout_16.addItem(spacerItem10)
        spacerItem11 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout_16.addItem(spacerItem11)
        spacerItem12 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout_16.addItem(spacerItem12)
        self.verticalLayout_12.addLayout(self.horizontalLayout_16)
        self.verticalLayout_17.addLayout(self.verticalLayout_12)
        self.verticalLayout_14 = QtWidgets.QVBoxLayout()
        self.verticalLayout_14.setObjectName("verticalLayout_14")
        self.textEdit_4 = QtWidgets.QTextEdit(parent=self.tab_2)
        self.textEdit_4.setObjectName("textEdit_4")
        self.verticalLayout_14.addWidget(self.textEdit_4)
        self.horizontalLayout_18 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_18.setObjectName("horizontalLayout_18")
        self.lineEdit_12 = QtWidgets.QLineEdit(parent=self.tab_2)
        self.lineEdit_12.setObjectName("lineEdit_12")
        self.horizontalLayout_18.addWidget(self.lineEdit_12)
        self.pushButton_13 = QtWidgets.QPushButton(parent=self.tab_2)
        font = QtGui.QFont()
        font.setPointSize(11)
        self.pushButton_13.setFont(font)
        self.pushButton_13.setObjectName("pushButton_13")
        self.horizontalLayout_18.addWidget(self.pushButton_13)
        self.verticalLayout_14.addLayout(self.horizontalLayout_18)
        self.verticalLayout_17.addLayout(self.verticalLayout_14)
        self.horizontalLayout_19.addLayout(self.verticalLayout_17)
        self.tabWidget.addTab(self.tab_2, "")
        self.verticalLayout.addWidget(self.tabWidget)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(parent=MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 934, 22))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(parent=MainWindow)
        font = QtGui.QFont()
        font.setPointSize(11)
        self.statusbar.setFont(font)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        self.tabWidget.setCurrentIndex(1)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.groupBox.setTitle(_translate("MainWindow", "服务器配置:"))
        self.label.setText(_translate("MainWindow", "服务端IP地址:"))
        self.lineEdit.setText(_translate("MainWindow", "127.0.0.1"))
        self.pushButton_3.setText(_translate("MainWindow", "使用本机IP地址"))
        self.label_2.setText(_translate("MainWindow", "服务器端口:"))
        self.lineEdit_2.setText(_translate("MainWindow", "12000"))
        self.pushButton.setText(_translate("MainWindow", "启动服务"))
        self.pushButton_2.setText(_translate("MainWindow", "停止服务"))
        self.pushButton_4.setText(_translate("MainWindow", "发送"))
        self.groupBox_2.setTitle(_translate("MainWindow", "客户端配置"))
        self.label_4.setText(_translate("MainWindow", "服务器IP:"))
        self.lineEdit_5.setText(_translate("MainWindow", "127.0.0.1"))
        self.label_5.setText(_translate("MainWindow", "服务器端口:"))
        self.lineEdit_6.setText(_translate("MainWindow", "12000"))
        self.pushButton_5.setText(_translate("MainWindow", "连接服务器"))
        self.pushButton_6.setText(_translate("MainWindow", "断开连接"))
        self.pushButton_7.setText(_translate("MainWindow", "发送"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "TCP协议"))
        self.groupBox_3.setTitle(_translate("MainWindow", "服务器设置"))
        self.label_3.setText(_translate("MainWindow", "服务器IP地址:"))
        self.lineEdit_3.setText(_translate("MainWindow", "127.0.0.1"))
        self.label_6.setText(_translate("MainWindow", "服务器端口:"))
        self.lineEdit_8.setText(_translate("MainWindow", "12000"))
        self.pushButton_8.setText(_translate("MainWindow", "启动服务"))
        self.pushButton_12.setText(_translate("MainWindow", "发送"))
        self.groupBox_4.setTitle(_translate("MainWindow", "客户端设置"))
        self.label_7.setText(_translate("MainWindow", "服务器IP地址:"))
        self.lineEdit_9.setText(_translate("MainWindow", "127.0.0.1"))
        self.label_8.setText(_translate("MainWindow", "服务器端口:"))
        self.lineEdit_10.setText(_translate("MainWindow", "12000"))
        self.pushButton_13.setText(_translate("MainWindow", "发送"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "UDP协议"))

7、程序启动代码

import sys
from module.main import MainWindow
from PyQt6.QtWidgets import QApplication

if __name__ == '__main__':
    app = QApplication(sys.argv)
    login = MainWindow()
    sys.exit(app.exec())

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/221465.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

我在USC南加大学游戏:真实经历/录取作品集_RoSSo艺术留学

近日,美国Common App最新早申统计数据:早申人数与疫情前相比增加了41%!专注于国际艺术教育的RoSSo也发现,2022-2023申请季提交早申的学生中,各类热门院校以及艺术留学专业申请人数均是“涨”声一片! 图源官…

30、pytest入门内容回顾

整体结构 解读与实操 pytest30讲主要从四个方面由浅入深的进行解读, 开始 讲解了pytest的概述,安装前的准备工作(python,pycharm,pytest),运行方式(命令行),断言(assert…

Linux(统信UOS) 发布.Net Core,并开启Https,绑定证书

实际开发中,有时会需要为小程序或者需要使用https的应用提供API接口服务,这就需要为.Net Core 配置https,配置起来很简单,只需要在配置文件appsettings.json中添加下面的内容即可 "Kestrel": {"Endpoints": …

nodejs+vue+微信小程序+python+PHP天天网站书城管理系统的设计与实现-计算机毕业设计推荐

本项目主要分为前台模块与后台模块2个部分,详细描述如下:   (1)前台模块 首页: 首页可以起到导航的作用,用户想要了解网站 ,网站首页为用户可以深入了解网站提供了一个平台,它就向一个“导游”…

Bionorica成功完成SAP S/4HANA升级 提升医药制造业务效率

企业如何成功地将其现有的ERP ECC系统转换升级到SAP S/4HANA, 并挖掘相关潜力来推动其数字化战略?Bionorica应用SNP软件实施了实时ERP套件,为进一步的增长和未来的创新奠定了基础。 草药市场的领导者:Bionorica Bionorica是世界领…

数据挖掘 分类模型选择

选择的模型有: 决策树、朴素贝叶斯、K近邻、感知机 调用的头文件有: import numpy as np import pandas as pd from matplotlib import pyplot as plt from sklearn.linear_model import Perceptron from sklearn.naive_bayes import GaussianNB from s…

软件测试面试题解析--什么题是必问的?

设计测试用例的主要方法有哪些?简述一下缺陷的生命周期?测试流程?项目流程?验收测试中和β测试区别?如何维护测试用例?每天测多少用例怎么分配的测试的一天能找多少bug你在上一家公司,写没写过测…

github首次将文件合到远端分支,发现名字不是master,而是main

暂存区和本地仓库的信息都存储在.git目录中其中 其中,暂存区和本地仓库的信息都存储在.git目录中 在自己的github上实践 1、刚开始,git clone gitgithub.com:lingze8678/my_github.git到本地 2、在克隆后的代码中加入一个pdf文件 3、在git bash中操作…

基本网络安全概述:保护您的数字生活

数字时代给我们的生活带来了无与伦比的连通性和便利,但也带来了新的威胁和漏洞。随着我们越来越依赖技术,网络安全概述的重要性怎么强调都不为过。在这篇文章中,我们将深入探讨网络安全的重要性、其关键组成部分、最佳实践、常见威胁以及该领…

WeakMap

WeakMap简介 作为es6一种新的数据结构,他是一种键值对的集合。与Map最大的区别有两个 1. 是其中的键必须是对象或非全局注册的符号。 全局注册的符号 const s1 Symbol.for(mySymbol) 非全局注册的符号 const s1 Symbol(mySymbol)了解Symbol.for 2. 不会创建对它…

Ansys Zemax | 手机镜头设计 - 第 3 部分:使用 STAR 模块和 ZOS-API 进行 STOP 分析

附件下载 联系工作人员获取附件 本文是 3 篇系列文章的一部分,该系列文章将讨论智能手机镜头模组设计的挑战,从概念、设计到制造和结构变形的分析。本文是三部分系列的第三部分。它涵盖了使用 Ansys Zemax OpticStudio Enterprise 版本提供的 STAR 技术…

ATECLOUD电源自动测试系统打破传统 助力新能源汽车电源测试

随着新能源汽车市场的逐步扩大,技术不断完善提升,新能源汽车测试变得越来越复杂,测试要求也越来越严格。作为新能源汽车的关键部件之一,电源为各个器件和整个电路提供稳定的电源,满足需求,确保新能源汽车的…

Homework 3: Higher-Order Functions, Self Reference, Recursion, Tree Recursion

Q1: Compose 编写一个高阶函数composer,它返回两个函数func和func_adder。 func是一个单参数函数,它应用到目前为止已经组合的所有函数。这些函数将首先应用最新的函数(参见doctests和示例)。 func_adder用于向我们的组合添加更多…

ESP32-Web-Server编程-在网页中插入图片

ESP32-Web-Server编程-在网页中插入图片 概述 图胜与言,在网页端显示含义清晰的图片,可以使得内容更容易理解。 需求及功能解析 本节演示在 ESP32 Web 服务器上插入若干图片。在插入图片时还可以对图片设置一个超链接,用户点击该图片时&a…

统计项目代码行数轻松搞定:使用 Node.js 脚本自动统计代码量

说在前面 在软件开发领域,了解项目的代码规模和复杂度对于项目管理、团队协作以及技术评估都至关重要。通过统计项目代码行数,我们能够更好地把握项目的整体情况,包括但不限于代码量的大小、不同类型文件的分布情况以及项目的结构和复杂度。这…

数据结构之选择排序

目录 直接选择排序 选择排序的时间复杂度 堆排序 向上调整算法 向下调整算法 向上调整算法建立堆 向下调整算法建立堆 堆排序整体代码 堆排序的时间复杂度 直接选择排序 在之前讲插入排序时,我们讲了这样的一个应用场景,我们在斗地主摸牌时&…

CoreDNS实战(十一)-分流与重定向

本文主要介绍了目前CoreDNS服务在外部域名递归结果过程中出现的一些问题以及使用dnsredir插件进行分流和alternate插件进行重试优化的操作。 1 自建DNS服务现状 一般来说,无论是bind9、coredns、dnsmasq、pdns哪类dns服务器,我们自建的监听在UDP53端口…

【已解决】页内切换<router-view>使得url变化导致菜单高亮消失

在写项目时&#xff0c;我们常会用到侧边菜单栏&#xff0c;而具体页面中经常使用<router-view>切换子组件。 但是按照我们平时的写法&#xff0c;切换子组件后会导致url改变&#xff0c;从而使得菜单高亮消失&#xff0c;这是非常影响用户体验的。 所以&#xff0c;我…

圈子社交系统:打破时间与空间的限制。APP小程序H5三端源码交付,支持二开!

在现代社会&#xff0c;社交已成为人们生活中不可或缺的一部分。然而&#xff0c;传统的社交方式往往受制于时间和空间的限制&#xff0c;使得人们难以充分发挥社交的潜力。为了解决这一问题&#xff0c;圈子社交系统应运而生。 圈子社交系统通过技术手段打破时间与空间的限制&…

想考研到电子类,未来从事芯片设计,目前该怎么准备?

最近看不少天坑学子想考研微电子专业&#xff0c;但却不知道该怎么准备&#xff1f;接下来就带大家一起来具体了解一下~ 首先是目标院校的选择&#xff1f; 目前所设的微电子专业学校里&#xff0c;比较厉害的有北京大学、清华大学、中国科学院大学、复旦大学、上海交通大学、…