python socket编程6 - 使用PyQt6 开发UI界面实现TCP server和TCP client单机通讯的例子
使用PyQt6 开发UI界面实现TCP server和TCP client单机通讯的示例。
一、PyQt6 实现的界面

二、TCP server代码的修改示意

界面提供网络参数的配置,以及提供人机交互过程中的数据获取和显示。
1、把上面的server代码封装成两个部分
A、class Server 负责接受UI界面的参数并通过信号与后台线程通讯
B、class ServerSocketReceiveThread 封装了 server socket 接收数据的行为并提供信号与Server交换数据
如果在UI界面调用while语句接收socket数据,会导致界面卡死。
所以使用新线程运行socket接收数据的操作,通过信号传递给Server中定义的方法,实现数据传递。
下图是原来的代码与修改后的代码部分映射的关系:

2、Server的完整代码
class Server: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 # socketself.socketThread = None # 新的 socket receive 线程self.start()def start(self):if not self.is_running:self.is_running = Trueself.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 = Falseif self.socketThread.is_running:self.socketThread.stop()except Exception as e:print(e)def startSocketReceiveThread(self):self.socketThread = ServerSocketReceiveThread(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)
3、ServerSocketReceiveThread 完整代码
class ServerSocketReceiveThread(QThread):clientConnection: pyqtSignal = pyqtSignal(str) # 向主线程发送连接状态标志receivedClientData: pyqtSignal = pyqtSignal(str) # 向主线程发送接受到客户端的数据serverStatus: pyqtSignal = pyqtSignal(str) # 向主线程发送服务器状态def __init__(self, serverSocket):super(ServerSocketReceiveThread, self).__init__()self.serverSocket = serverSocketself.clientSocket = Noneself.addr = Noneself.is_running = Truedef 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') if not data:self.emitConnectEvent('disconnect') # 发送通知到主界面breakself.sendClientDataToUi(data)except ConnectionResetError as reason:self.sendClientDataToUi("已经离开对话。")self.is_running = Falseself.emitConnectEvent('disconnect') # 发送通知到主界面breakself.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 = Falsedef emitConnectEvent(self, state):self.clientConnection.emit(state)def sendClientDataToUi(self, message):self.receivedClientData.emit(message)
三、TCP Client 代码也是同样封装为两部分
1、class Client完整代码
class Client:def __init__(self, ui, ip, clientName, port):self.ui = uiself.ip = ipself.hostName = clientNameself.port = portself.socket = Noneself.socketThread = Noneself.connect_server()def connect_server(self):self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)self.socketThread = ClientSocketReceiveThread(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 Trueexcept Exception as reason:print(reason)return False
2、class ClientSocketReceiveThread完整代码
class ClientSocketReceiveThread(QThread):receivedServerData: pyqtSignal = pyqtSignal(str) # 向主线程发送接受到客户端的数据def __init__(self, clientSocket):super(ClientSocketReceiveThread, self).__init__()self.clientSocket = clientSocketself.is_running = Truedef stop(self):self.is_running = Falseself.clientSocket.close()def run(self):while self.is_running:try:msg = self.clientSocket.recv(1024).decode("utf-8") # 接受服务端消息if not msg:breakself.receivedServerData.emit(msg)except Exception as reason:print(reason)breakself.stop()self.receivedServerData.emit("已经与服务端断开。")
四、ui_Main.py代码
class Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(957, 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.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, 957, 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(0)QtCore.QMetaObject.connectSlotsByName(MainWindow)def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.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.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "UDP协议"))
五、application.py 启动代码
import os
import sys
from module.main import MainWindow
from PyQt6.QtWidgets import QApplicationif __name__ == '__main__':app = QApplication(sys.argv)login = MainWindow()sys.exit(app.exec())
六、main.py 代码
from PyQt6 import QtWidgets
from .server import Server
from .client import Client
from ui.ui_Main import Ui_MainWindowclass MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):"""主窗口初始化"""def __init__(self):super(MainWindow, self).__init__()self.setupUi(self)self.show()self.pushButton.clicked.connect(self.server_start)self.pushButton_2.clicked.connect(self.server_stop)self.pushButton_4.clicked.connect(self.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.server = Noneself.client = Nonedef client_connect_server(self):server_ip = self.lineEdit_5.text()server_port = int(self.lineEdit_6.text())client_name = '客户端'self.client = Client(self, server_ip, client_name, server_port)def client_disconnect_server(self):self.client.stop()def client_send_data(self):message = self.lineEdit_7.text()self.client.send_data(message)def server_start(self):server_ip = self.lineEdit.text()server_port = int(self.lineEdit_2.text())server_name = '服务器'self.server = Server(self, server_ip, server_name, server_port)def server_stop(self):self.server.stop()def server_send_data(self):message = self.lineEdit_4.text()self.server.send_message_to_client(message)

相关文章:
python socket编程6 - 使用PyQt6 开发UI界面实现TCP server和TCP client单机通讯的例子
使用PyQt6 开发UI界面实现TCP server和TCP client单机通讯的示例。 一、PyQt6 实现的界面 二、TCP server代码的修改示意 界面提供网络参数的配置,以及提供人机交互过程中的数据获取和显示。 1、把上面的server代码封装成两个部分 A、class Server 负责接受UI界面…...
centos上安装并持久化配置LVS
1 实验背景 1)系统版本:centos7.8 2)虚拟机:3个centos虚拟机,(其中一个做Director Server,另外两个做Real Server) 3) LVS大致有NAT ,DR ,Tun这三种模式,这里搭建一个典型的DR模式的LVS Direc…...
多线程并发Ping脚本
1. 前言 最近需要ping地址,还是挺多的,就使用python搞一个ping脚本,记录一下,以免丢失了。 2. 脚本介绍 首先检查是否存在True.txt或False.txt文件,并在用户确认后进行删除,然后从IP.txt的文件中读取IP地…...
SpringBoot Seata 死锁问题排查
现象描述:Spring Boot项目,启动的时候卡住了,一直卡在那里不动,没有报错,也没有日志输出 但是,奇怪的是,本地可以正常启动 好吧,姑且先不深究为什么本地可以启动而部署到服务器上就无…...
文章解读与仿真程序复现思路——电力系统自动化EI\CSCD\北大核心《考虑两阶段鲁棒优化配置的多微网合作博弈》
这个标题涉及到多个概念,让我们逐步解读: 考虑两阶段鲁棒优化配置: 两阶段: 指的是在解决问题或进行优化时,可能存在两个不同的阶段或步骤。这表明问题的解决不是一步完成的,而是需要经过多个步骤或阶段。鲁…...
Redis常见类型
常用类型String字符串类型Hash字典类型List列表类型Set集合类型ZSet有序集合类型 Java程序操作Redis类型代码操作Redis 常用类型 String字符串类型 使用方式: 使用场景: Hash字典类型 字典类型(Hash) 又被成为散列类型或者是哈希表类型࿰…...
深入了解数据库锁:类型、应用和最佳实践
目录 1. 引言 2. 数据库锁的基本概念 2.1 悲观锁和乐观锁 2.2 排他锁和共享锁 3. 悲观锁的应用场景 3.1 长事务和大事务 3.2 并发修改 3.3 数据库死锁 4. 悲观锁的最佳实践 4.1 精细控制锁的粒度 4.2 避免死锁 4.3 考虑乐观锁 5. 案例分析 5.1 银行系统的转账操作…...
python3.5安装教程及环境配置,python3.7.2安装与配置
大家好,小编来为大家解答以下问题,python3.5安装教程及环境配置,python3.7.2安装与配置,现在让我们一起来看看吧! python 从爬虫开始(一) Python 简介 首先简介一下Python和爬虫的关系与概念&am…...
ubuntu安装tomcat并配置前端项目
1.1查找 # 先更新 sudo apt update # 查找 apt search jdk1.2安装 sudo apt install openjdk-8-jdk1.3验证 java -version 2.安装tomcat 下载链接:Apache Tomcat - Apache Tomcat 8 Software Downloadshttps://tomcat.apache.org/download-80.cgi下载这个&…...
GeoPandas初体验:它是什么,我用它展示一下shp矢量数据
GeoPandas 是一个开源的 Python 库,用于处理地理空间数据。它扩展了 Pandas 这个流行的 Python 数据操作库,增加了对地理数据类型和操作的支持。GeoPandas 结合了 Pandas、Matplotlib 和 Shapely 的功能,提供了一个易于使用且高效的工具&…...
Python-滑雪大冒险【附源码】
滑雪大冒险 《滑雪大冒险》是一款充满趣味性和挑战性的休闲竞技游戏,在游戏中,玩家将扮演一位勇敢的滑雪者,在雪山上展示他们的滑雪技巧,游戏采用2D图形界面,以第三人称视角呈现 运行效果:用方向键及方向键…...
Linux---日志管理
本章主要介绍Linux中的日志管理 了解rsyslog是如何管理日志的查看日志的方法 日志管理简介 工作当中的日志,特指硬件和软件的日志,管理员可以通过它来检查错误发生的原因,或者寻找受到攻击时攻击者留下的痕迹。日志管理包括管理系统日志、应…...
Java高级技术-单元测试
单元测试 Junit单元测试框架 Junit单元测试-快速入门 方法类 测试类 Junit框架的基本注解...
springboot集成邮箱验证功能
准备工作 开启SMTP服务 前往你的邮箱网站,以网易邮箱为例,打开网易邮箱地址,登录你的邮箱,进入邮箱管理后台界面。点击“设置”》》“POP3/SMTP/IMAP”后,点击开启SMTP服务即可。 技术实现 Spring Boot 发送邮件验证…...
HarmonyOS应用程序框架——UIAbility实操
UIAbility概述 UIAbility是一种包含用户界面的应用组件,主要用于和用户进行交互。UIAbility也是系统调度的单元,为应用提供窗口在其中绘制界面。 每一个UIAbility实例,都对应于一个最近任务列表中的任务。 一个应用可以有一个UIAbility&…...
数实融合!低代码推动工业数字化转型走“深”向“实”
当下,“数字化、智能化”已经不再是新鲜词。毕竟,在早几年前就已经有企业喊出大举进军数字化的口号,轰轰烈烈的数字化转型运动也持续了很长一段时间,有一些业内人士甚至判断“如今的企业数字化已经走过了成熟期,来到了…...
OpenGL学习资料
1.学习网站 Song Ho Ahn LearnOpenGL GAMES101:现代计算机图形学入门 OpenGL 官网 2.书籍 Fundamentals of computer graphics OpenGL ES 3.0编程指南 计算机图形学(OpenGL版)第3版 3.参考的一些文章 颜色缓冲区 深度缓冲 VBO,VAO和EBO详解 深入探索透视投影变…...
字符串指令集
字符串指令的格式 例子1就成功发送了指令 例子2就是发送的字符串有误 查询当前位置就会在附加信息中返回当前座位的坐标 第一个指令的参数就是闪灯的两个参数 如第一个示例就是10ms On Time 第二个就是Off Time 使用标准库来接收字符串命令 字符串指令的接收 因为一个指令就是…...
行云海CMS SQL注入漏洞复现
0x01 产品简介 行云海cms是完全开源的一套CMS内容管理系统,简洁,易用,安全,稳定,免费。 0x02 漏洞概述 行云海cms中ThinkPHP在处理order by排序时可利用key构造SQL语句进行注入,LtController.class.php中发现传入了orderby未进行过滤导致sql注入。攻击者除了可以利用 SQL 注入…...
窗口函数之 first_value() 和 last_value()
这次,我要从**last_value()**开始写! last_value() 众所周知,first_value() 和 last_value() 的作用是返回窗口中某个字段的第一行的值和最后一行的值。 但是在应用的时候,突然发现使用last_value() 返回了不止一条数据&#x…...
7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
