GUI 應用:socket 網絡聊天室

在這個周末剛剛寫出來的python桌面應用--網絡聊天室,主要通過pyqt5作為桌面應用框架,socket作為網絡編程的框架,從而實現包括客戶端和服務端的網絡聊天室的GUI應用,希望可以一起學習、一起進步!

網站建設哪家好,找成都創新互聯公司!專注于網頁設計、網站建設、微信開發、重慶小程序開發、集團企業網站建設等服務項目。為回饋新老客戶創新互聯還提供了博愛免費建站歡迎大家使用!

應用包括服務端server_ui.py、客戶端client_ui.py兩個python模塊實現,并且在pyqt5的使用過程中都使用QThread多線程應用以及基本的UI頁面布局。開始之前通過一個動態圖來觀察一下socket服務端、socket客戶端通信的實現效果。

【閱讀全文】

  1. socket_ui.py 服務端

1-1. 依賴引用

在socket服務端的實現過程中,除了pyqt5相關的UI界面的引用外,還包括time、threading、sys、socket等輔助模塊來一起實現socket服務端的桌面應用程序。

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import sys

from QCandyUi import CandyWindow

# 導入 socket 通訊模塊
import socket
# 導入時間管理模塊
import time
# 導入多線程模塊
import threading

1-2. 實現過程

在服務端的業務實現上面,我們依然是按照之前的GUI實現方式,采用主線程用來實現頁面布局,子線程QThread來實現業務邏輯的方式來進行實現的,socket的服務端通信業務都是在子線程ServerThread中編寫的。下面是socket服務端桌面應用實現的全部代碼塊,copy到自己的ide中即可直接啟動使用。

class ServerUI(QWidget):
    def __init__(self):
        super(ServerUI, self).__init__()
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle('socket 服務端  公眾號:[Python 集中營]')
        self.setWindowIcon(QIcon('hi.ico'))
        self.setFixedSize(500, 300)

        hbox = QHBoxLayout()

        hbox_v1 = QVBoxLayout()
        self.brower = QTextBrowser()
        self.brower.setFont(QFont('宋體', 8))
        self.brower.setReadOnly(True)
        self.brower.setPlaceholderText('消息展示區域...')
        self.brower.ensureCursorVisible()
        hbox_v1.addWidget(self.brower)

        hbox_v2 = QVBoxLayout()

        hbox_v2_f1 = QFormLayout()
        self.ip_label = QLabel()
        self.ip_label.setText('ip地址 ')
        self.ip_txt = QLineEdit()
        self.ip_txt.setPlaceholderText('0.0.0.0')

        self.port_label = QLabel()
        self.port_label.setText('端口 ')
        self.port_txt = QLineEdit()
        self.port_txt.setPlaceholderText('4444')

        self.lis_num_label = QLabel()
        self.lis_num_label.setText('最大監聽個數 ')
        self.lis_num_txt = QLineEdit()
        self.lis_num_txt.setPlaceholderText('10')

        self.close_cli_label = QLabel()
        self.close_cli_label.setText('客戶端關閉指令 ')
        self.close_cli_txt = QLineEdit()
        self.close_cli_txt.setPlaceholderText('exit,客戶端發送相應指令則關閉')

        hbox_v2_f1.addRow(self.ip_label, self.ip_txt)
        hbox_v2_f1.addRow(self.port_label, self.port_txt)
        hbox_v2_f1.addRow(self.lis_num_label, self.lis_num_txt)
        hbox_v2_f1.addRow(self.close_cli_label, self.close_cli_txt)

        self.start_btn = QPushButton()
        self.start_btn.setText('開啟服務端')
        self.start_btn.clicked.connect(self.start_btn_clk)

        hbox_v2.addLayout(hbox_v2_f1)
        hbox_v2.addWidget(self.start_btn)

        hbox.addLayout(hbox_v1)
        hbox.addLayout(hbox_v2)

        self.thread_ = ServerThread(self)
        self.thread_.message.connect(self.show_message)

        self.setLayout(hbox)

    def show_message(self, text):
        '''
        槽函數:向文本瀏覽器中寫入內容
        :param text:
        :return:
        '''
        cursor = self.brower.textCursor()
        cursor.movePosition(QTextCursor.End)
        self.brower.append(text)
        self.brower.setTextCursor(cursor)
        self.brower.ensureCursorVisible()

    def start_btn_clk(self):
        self.thread_.start()
        self.start_btn.setEnabled(False)


class ServerThread(QThread):
    message = pyqtSignal(str)

    def __init__(self, parent=None):
        super(ServerThread, self).__init__(parent)
        self.parent = parent
        self.working = True

    def __del__(self):
        self.working = False
        self.wait()

    def run(self):
        self.message.emit('準備啟動socket服務端...')
        # 創建服務端 socket
        socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 綁定服務地址、端口
        address = (self.parent.ip_txt.text().strip(), int(self.parent.port_txt.text().strip()))
        socket_server.bind(address)
        # 設置監聽最大等待數
        socket_server.listen(int(self.parent.lis_num_txt.text().strip()))
        self.message.emit("服務已經啟動,正在等待客戶端連接...")
        while True:
            # 設置睡眠時間
            time.sleep(0.1)
            # 允許客戶端連接
            client, info = socket_server.accept()
            self.client, self.info = client, info
            # 啟用新線程調用消息處理
            thread = threading.Thread(target=self.catch_message)
            # 設置為守護線程
            thread.setDaemon(True)
            # 開啟線程執行
            thread.start()

    def catch_message(self):
        self.client.send("歡迎來到網絡聊天室".encode('utf-8'))
        self.message.emit("客戶端信息:" + str(self.info))
        close_cli = self.parent.close_cli_txt.text().strip()
        while True:
            try:
                #  接收客戶端消息、接收最大長度為 1024,并進行 utf-8 解碼
                message = self.client.recv(1024).decode('utf-8')
                # 校驗是否關閉客戶端
                if not message and close_cli == message:
                    self.client.close()
                    self.message.emit("當前客戶端已關閉!")
                    break
                self.message.emit("接收到消息:" + message)
                # 將消息進行 utf-8 編碼后發給客戶端
                rcv = "服務端成功接收消息:" + message
                self.client.send(rcv.encode('utf-8'))
            except Exception as e:
                self.client.send("服務端處理消息異常!".encode('utf-8'))
                break


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = CandyWindow.createWindow(ServerUI(), theme='blueGreen', title='socket 服務端  公眾號:[Python 集中營]',
                                 ico_path='hi.ico')
    w.show()
    sys.exit(app.exec_())

1-3. 實現效果

  1. client_ui.py 客戶端

2-1. 依賴引用

在socket客戶端的實現過程中,除了pyqt5相關的UI界面的引用外,還包括sys、socket等輔助模塊來一起實現socket服務端的桌面應用程序,相比服務端來說,客戶端并沒有使用多線程threading模塊。

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import sys

from QCandyUi import CandyWindow

# 導入socket 通信模塊
import socket

2-2. 實現過程

客戶端的實現過程和服務端server_ui.py實現是基本相似的,同樣也使用到了pyqt5的QThread的子線程應用,唯一不同的是socket客戶端通信方式跟服務端不大相同,同樣將下面的代碼塊copy到自己的ide中直接使用即可。

class ClientUI(QWidget):
    def __init__(self):
        super(ClientUI, self).__init__()
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle('socket 客戶端  公眾號:[Python 集中營]')
        self.setWindowIcon(QIcon('hi.ico'))
        self.setFixedSize(500, 300)

        hbox = QHBoxLayout()

        hbox_v1 = QVBoxLayout()
        self.brower = QTextBrowser()
        self.brower.setFont(QFont('宋體', 8))
        self.brower.setReadOnly(True)
        self.brower.setPlaceholderText('消息展示區域...')
        self.brower.ensureCursorVisible()
        hbox_v1.addWidget(self.brower)

        hbox_v2 = QVBoxLayout()

        hbox_v2_g1 = QGridLayout()
        self.ip_label = QLabel()
        self.ip_label.setText('ip地址 ')
        self.ip_txt = QLineEdit()
        self.ip_txt.setPlaceholderText('0.0.0.0')

        self.port_label = QLabel()
        self.port_label.setText('端口 ')
        self.port_txt = QLineEdit()
        self.port_txt.setPlaceholderText('4444')

        self.message = QTextEdit()
        self.message.setPlaceholderText('發送消息內容...')

        hbox_v2_g1.addWidget(self.ip_label, 0, 0, 1, 1)
        hbox_v2_g1.addWidget(self.ip_txt, 0, 1, 1, 1)

        hbox_v2_g1.addWidget(self.port_label, 1, 0, 1, 1)
        hbox_v2_g1.addWidget(self.port_txt, 1, 1, 1, 1)

        hbox_v2_g1.addWidget(self.message, 2, 0, 1, 2)

        self.start_btn = QPushButton()
        self.start_btn.setText('發送消息')
        self.start_btn.clicked.connect(self.start_btn_clk)

        hbox_v2.addLayout(hbox_v2_g1)
        hbox_v2.addWidget(self.start_btn)

        hbox.addLayout(hbox_v1)
        hbox.addLayout(hbox_v2)

        self.thread_ = ClientThread(self)
        self.thread_.message.connect(self.show_message)

        self.setLayout(hbox)

    def show_message(self, text):
        '''
        槽函數:向文本瀏覽器中寫入內容
        :param text:
        :return:
        '''
        cursor = self.brower.textCursor()
        cursor.movePosition(QTextCursor.End)
        self.brower.append(text)
        self.brower.setTextCursor(cursor)
        self.brower.ensureCursorVisible()

    def start_btn_clk(self):
        self.thread_.start()


class ClientThread(QThread):
    message = pyqtSignal(str)

    def __init__(self, parent=None):
        super(ClientThread, self).__init__(parent)
        self.parent = parent
        self.working = True
        self.is_connect = False

    def __del__(self):
        self.working = False
        self.wait()

    def run(self):
        try:
            if self.is_connect is False:
                self.connect_serv()
            # 將控制臺輸入消息進行 utf-8 編碼后發送
            self.socket_client.send(self.parent.message.toPlainText().strip().encode('utf-8'))
            self.message.emit(self.socket_client.recv(1024).decode('utf-8'))
        except Exception as e:
            self.message.emit("發送消息異常:" + str(e))

    def connect_serv(self):
        try:
            self.message.emit("正在創建客戶端socket...")
            # 創建客戶端 socket
            self.socket_client = socket.socket()
            # 連接服務端
            address = (self.parent.ip_txt.text().strip(), int(self.parent.port_txt.text().strip()))
            self.socket_client.connect(address)
            self.message.emit("服務端連接成功...")
            # 接收服務端消息并進行 utf-8 解碼
            self.message.emit(self.socket_client.recv(1024).decode())
            self.is_connect = True
        except:
            self.is_connect = False


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = CandyWindow.createWindow(ClientUI(), theme='blueGreen', title='socket 客戶端  公眾號:[Python 集中營]',
                                 ico_path='hi.ico')
    w.show()
    sys.exit(app.exec_())

2-3. 實現效果

【往期精彩】

零配置python日志,安裝即用!

英語沒學好到底能不能做coder,別再糾結了先學起來...

數據清洗工具flashtext,效率直接提升了幾十倍數!

一個help函數解決了python的所有文檔信息查看...

python 自定義異常/raise關鍵字拋出異常

分享名稱:GUI 應用:socket 網絡聊天室
文章起源:http://m.kartarina.com/article22/dsoggjc.html

成都網站建設公司_創新互聯,為您提供虛擬主機品牌網站制作企業建站網站建設網站營銷外貿建站

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

手機網站建設
主站蜘蛛池模板: 久久久久亚洲av无码专区蜜芽| 国产精品无码素人福利不卡| 中文字幕av无码专区第一页| 欧洲人妻丰满av无码久久不卡 | 国产av无码专区亚洲av果冻传媒| 亚洲成AV人在线播放无码| 无码毛片内射白浆视频| 中文字幕无码视频手机免费看| 日韩精品无码一本二本三本 | 国产精品热久久无码av| 无码精品一区二区三区在线| 粉嫩大学生无套内射无码卡视频 | 无码少妇一区二区三区| 亚洲成a∨人片在无码2023| 无码夫の前で人妻を侵犯| 亚洲?V无码成人精品区日韩 | 夫妻免费无码V看片| 亚洲国产精品无码久久98| 亚洲heyzo专区无码综合| 国产成人精品无码片区在线观看| 无码人妻精品一区二区蜜桃| 无码精品黑人一区二区三区 | 中文字幕无码一区二区免费| 无码中文人妻在线一区 | 成在人线AV无码免费| 国产50部艳色禁片无码| 亚洲一级特黄大片无码毛片| 蜜芽亚洲av无码一区二区三区| 在线看无码的免费网站| 无码任你躁久久久久久老妇App | 亚洲av无码偷拍在线观看| 日韩一区二区三区无码影院| 国产精品VA在线观看无码不卡| 自拍偷在线精品自拍偷无码专区| 亚洲av无码天堂一区二区三区| 日韩少妇无码一区二区三区| 国产人成无码视频在线观看| 中文字幕无码人妻AAA片| 亚洲日韩VA无码中文字幕| 中文字幕无码一区二区三区本日| 亚洲Av永久无码精品三区在线|