PyQt5可编辑下拉框(comboBox):editable - python TCP服务器v1.5 - 客户端连接界面增加自定义参数(设置超时, 连接地址可选)

18 篇文章 1 订阅
16 篇文章 0 订阅

TCP聊天服务器套接字v1.5

所有版本记录:
v1.0 : TCP聊天服务器套接字|PyQt5+socket(TCP端口映射+端口放行)+logging+Thread(含日志,html)+anaconda打包32位exe(3.4万字)|python高阶
v1.1 : python TCP套接字服务器v1.1-新增服务端命令功能及修改bug(socket+PyQt5)

v1.2 : python TCP服务器v1.2 - 服务端新增用户登录注册(json, md5加密)
v1.3 : python TCP服务器v1.3 - 服务器抗压测试及关闭套接字处理
v1.4 : python TCP服务器v1.4 - 客户端连接服务器异常(异常情况分类)处理

在这里插入图片描述

| ip格式

dicts = {f"103.46.128.21:51203 (公网)" : "103.46.128.21:51203",
         f"{get_host_ip()}:429 (私网)" : f"{get_host_ip()}:429",
         "EXAM-41:429          (微机室)" : "EXAM-41:429"}

def address_split(address):
    def func(ip="",port=0) -> (str, int):
        return ip,int(port)

    ip, port = func(*address.strip().split(':')[:2])
    return {"ip":ip,
            "port":port}

| 客户端连接界面增加自定义参数(设置超时, 连接地址可选(editable))

(1). 可编辑下拉框comboBox

在这里插入图片描述

(2).连接界面

python代码(pyuic5)

class Ui_Dialog(object):
    def __init__(self):
        Dialog = QtWidgets.QDialog()
        self.Dialog = Dialog
        Dialog.setObjectName("Dialog")
        Dialog.resize(532, 239)
        font = QtGui.QFont()
        font.setFamily("Consolas")
        Dialog.setFont(font)
        Dialog.setAutoFillBackground(True)
        Dialog.setStyleSheet("")
        self.gridLayout_3 = QtWidgets.QGridLayout(Dialog)
        self.gridLayout_3.setObjectName("gridLayout_3")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.label_3 = QtWidgets.QLabel(Dialog)
        self.label_3.setText("")
        self.label_3.setPixmap(QtGui.QPixmap("link.png"))
        self.label_3.setObjectName("label_3")
        self.horizontalLayout.addWidget(self.label_3)
        self.label_4 = QtWidgets.QLabel(Dialog)
        self.label_4.setObjectName("label_4")
        self.horizontalLayout.addWidget(self.label_4)
        self.gridLayout_3.addLayout(self.horizontalLayout, 0, 0, 1, 1)
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.gridLayout_3.addItem(spacerItem, 0, 1, 1, 1)
        self.progressBar = QtWidgets.QProgressBar(Dialog)
        self.progressBar.setMaximum(3)
        self.progressBar.setProperty("value", 0)
        self.progressBar.setObjectName("progressBar")
        self.gridLayout_3.addWidget(self.progressBar, 2, 0, 1, 1)
        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.gridLayout_3.addItem(spacerItem1, 2, 1, 1, 1)
        self.pushButton = QtWidgets.QPushButton(Dialog)
        self.pushButton.setObjectName("pushButton")
        self.gridLayout_3.addWidget(self.pushButton, 2, 2, 1, 1)
        self.groupBox = QtWidgets.QGroupBox(Dialog)
        self.groupBox.setObjectName("groupBox")
        self.gridLayout_2 = QtWidgets.QGridLayout(self.groupBox)
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.label_2 = QtWidgets.QLabel(self.groupBox)
        font = QtGui.QFont()
        font.setFamily("Consolas")
        self.label_2.setFont(font)
        self.label_2.setTextFormat(QtCore.Qt.AutoText)
        self.label_2.setObjectName("label_2")
        self.gridLayout_2.addWidget(self.label_2, 2, 0, 1, 1)
        self.horizontalSlider = QtWidgets.QSlider(self.groupBox)
        self.horizontalSlider.setAutoFillBackground(False)
        self.horizontalSlider.setMinimum(1)
        self.horizontalSlider.setMaximum(10)
        self.horizontalSlider.setProperty("value", 3)
        self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal)
        self.horizontalSlider.setInvertedAppearance(False)
        self.horizontalSlider.setInvertedControls(False)
        self.horizontalSlider.setTickPosition(QtWidgets.QSlider.TicksBelow)
        self.horizontalSlider.setObjectName("horizontalSlider")
        self.gridLayout_2.addWidget(self.horizontalSlider, 4, 2, 1, 1)
        self.label = QtWidgets.QLabel(self.groupBox)
        font = QtGui.QFont()
        font.setFamily("Consolas")
        self.label.setFont(font)
        self.label.setObjectName("label")
        self.gridLayout_2.addWidget(self.label, 3, 0, 1, 1)
        self.comboBox = QtWidgets.QComboBox(self.groupBox)
        self.comboBox.setEditable(True)
        self.comboBox.setObjectName("comboBox")
        self.gridLayout_2.addWidget(self.comboBox, 3, 1, 1, 3)
        self.lineEdit_2 = QtWidgets.QLineEdit(self.groupBox)
        font = QtGui.QFont()
        font.setFamily("Consolas")
        self.lineEdit_2.setFont(font)
        self.lineEdit_2.setAccessibleDescription("")
        self.lineEdit_2.setInputMask("")
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.gridLayout_2.addWidget(self.lineEdit_2, 2, 1, 1, 3)
        self.gridLayout = QtWidgets.QGridLayout()
        self.gridLayout.setObjectName("gridLayout")
        self.label_5 = QtWidgets.QLabel(self.groupBox)
        self.label_5.setObjectName("label_5")
        self.gridLayout.addWidget(self.label_5, 0, 0, 1, 1)
        self.lcdNumber = QtWidgets.QLCDNumber(self.groupBox)
        self.lcdNumber.setStyleSheet("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, stop:0 rgba(0, 255, 223, 255), stop:0.631841 rgba(255, 255, 255, 255));\n"
"")
        self.lcdNumber.setFrameShadow(QtWidgets.QFrame.Raised)
        self.lcdNumber.setLineWidth(1)
        self.lcdNumber.setMidLineWidth(0)
        self.lcdNumber.setSegmentStyle(QtWidgets.QLCDNumber.Filled)
        self.lcdNumber.setProperty("intValue", 3)
        self.lcdNumber.setObjectName("lcdNumber")
        self.gridLayout.addWidget(self.lcdNumber, 0, 1, 1, 1)
        spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem2, 0, 2, 1, 1)
        self.gridLayout_2.addLayout(self.gridLayout, 4, 0, 1, 1)
        self.label_6 = QtWidgets.QLabel(self.groupBox)
        self.label_6.setStyleSheet("color:rgb(154, 154, 154);\n"
"font-size:13px")
        self.label_6.setObjectName("label_6")
        self.gridLayout_2.addWidget(self.label_6, 0, 0, 1, 1)
        self.gridLayout_3.addWidget(self.groupBox, 1, 0, 1, 3)
        self.lineEdit = QtWidgets.QLineEdit(Dialog)
        self.lineEdit.setReadOnly(True)
        self.lineEdit.setObjectName("lineEdit")
        self.gridLayout_3.addWidget(self.lineEdit, 3, 0, 1, 3)
        self.pushButton.setEnabled(False)
        self.retranslateUi(Dialog)
        self.pushButton.clicked.connect(self._connect)
        self.horizontalSlider.valueChanged['int'].connect(self.lcdNumber.display)
        self.horizontalSlider.valueChanged['int'].connect(self.set_timeout)
        QtCore.QMetaObject.connectSlotsByName(Dialog)
        self.lineEdit_2.textChanged.connect(lambda t: self.pushButton.setEnabled(bool(t.strip())))
        self.running = False
        self.timer = threading(True, target=self.add_bar)
    def add_bar(self):
        while True:
            if self.running and self.progressBar.value() < TIMEOUT:
                self.progressBar.setValue(self.progressBar.value() + 1)
                time.sleep(1)
    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowIcon(QtGui.QIcon('login.ico'))
        Dialog.setWindowTitle(_translate("Dialog", "connect"))
        self.label_4.setText(_translate("Dialog", f"{socket.gethostname()}"))
        self.progressBar.setFormat(_translate("Dialog", "%v / %m s"))
        self.pushButton.setText(_translate("Dialog", "Connecting"))
        self.groupBox.setTitle(_translate("Dialog", "Parameter Setup"))
        self.label_2.setText(_translate("Dialog", "用户名:"))
        self.horizontalSlider.setWhatsThis(_translate("Dialog", "set time out"))
        self.label.setText(_translate("Dialog", "Select Socket Connect Address:"))
        self.comboBox.addItems(dicts.keys())
        self.lineEdit_2.setPlaceholderText(_translate("Dialog", "≤8个字符,多余自动删去"))
        self.label_5.setText(_translate("Dialog", "最大超时秒数:"))
        self.label_6.setText(_translate("Dialog", "[i] 未注册的用户将自动注册"))
        self.lineEdit.setText(_translate("Dialog", "No return value."))
        Dialog.show()
    def set_timeout(self,t):
        global TIMEOUT
        TIMEOUT = int(t)
        self.progressBar.setMaximum(TIMEOUT)
    def set_text(self, m):
        self.lineEdit.setText(QtCore.QCoreApplication.translate("Dialog", str(m)))
        self.lineEdit.update()
    @to_logging
    def _connect(self, i):
        texts = self.comboBox.currentText()
        addr = address_split(dicts.get(texts, texts))
        global TIMEOUT
        TIMEOUT = self.horizontalSlider.value()
        global Username
        Username = self.lineEdit_2.text().strip()
        self.groupBox.setEnabled(False)
        self.progressBar.setValue(0)
        self.running = True
        self.set_text("[{}]: 尝试连接服务器[{}],最大超时报错 {}s".format(datetime.now().strftime('%Y %m %d %H:%M:%S'),addr["ip"],TIMEOUT))
        if s.connect(**addr, show=self.set_text):
            global main
            main = Ui_MainWindow()
            main.show()
            def close(widget):
                sleep(1)
                widget.close()
            threading(False, target=close, args=(self.Dialog, ))
        self.groupBox.setEnabled(True)
        self.running = False

.ui(xml)

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Dialog</class>
 <widget class="QDialog" name="Dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>532</width>
    <height>239</height>
   </rect>
  </property>
  <property name="font">
   <font>
    <family>Consolas</family>
   </font>
  </property>
  <property name="windowTitle">
   <string>connect</string>
  </property>
  <property name="autoFillBackground">
   <bool>true</bool>
  </property>
  <property name="styleSheet">
   <string notr="true"/>
  </property>
  <layout class="QGridLayout" name="gridLayout_3">
   <item row="0" column="0">
    <layout class="QHBoxLayout" name="horizontalLayout">
     <item>
      <widget class="QLabel" name="label_3">
       <property name="text">
        <string/>
       </property>
       <property name="pixmap">
        <pixmap>link.png</pixmap>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QLabel" name="label_4">
       <property name="text">
        <string>绑定主机{socket.gethostname()}</string>
       </property>
      </widget>
     </item>
    </layout>
   </item>
   <item row="0" column="1">
    <spacer name="horizontalSpacer">
     <property name="orientation">
      <enum>Qt::Horizontal</enum>
     </property>
     <property name="sizeHint" stdset="0">
      <size>
       <width>40</width>
       <height>20</height>
      </size>
     </property>
    </spacer>
   </item>
   <item row="2" column="0">
    <widget class="QProgressBar" name="progressBar">
     <property name="maximum">
      <number>3</number>
     </property>
     <property name="value">
      <number>0</number>
     </property>
     <property name="format">
      <string>%p / %m s</string>
     </property>
    </widget>
   </item>
   <item row="2" column="1">
    <spacer name="horizontalSpacer_4">
     <property name="orientation">
      <enum>Qt::Horizontal</enum>
     </property>
     <property name="sizeHint" stdset="0">
      <size>
       <width>40</width>
       <height>20</height>
      </size>
     </property>
    </spacer>
   </item>
   <item row="2" column="2">
    <widget class="QPushButton" name="pushButton">
     <property name="text">
      <string>Connecting</string>
     </property>
    </widget>
   </item>
   <item row="1" column="0" colspan="3">
    <widget class="QGroupBox" name="groupBox">
     <property name="title">
      <string>Parameter Setup</string>
     </property>
     <layout class="QGridLayout" name="gridLayout_2">
      <item row="2" column="0">
       <widget class="QLabel" name="label_2">
        <property name="font">
         <font>
          <family>Consolas</family>
         </font>
        </property>
        <property name="text">
         <string>用户名:</string>
        </property>
        <property name="textFormat">
         <enum>Qt::AutoText</enum>
        </property>
       </widget>
      </item>
      <item row="4" column="2">
       <widget class="QSlider" name="horizontalSlider">
        <property name="whatsThis">
         <string>set time out</string>
        </property>
        <property name="autoFillBackground">
         <bool>false</bool>
        </property>
        <property name="minimum">
         <number>1</number>
        </property>
        <property name="maximum">
         <number>10</number>
        </property>
        <property name="value">
         <number>3</number>
        </property>
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
        <property name="invertedAppearance">
         <bool>false</bool>
        </property>
        <property name="invertedControls">
         <bool>false</bool>
        </property>
        <property name="tickPosition">
         <enum>QSlider::TicksBelow</enum>
        </property>
       </widget>
      </item>
      <item row="3" column="0">
       <widget class="QLabel" name="label">
        <property name="font">
         <font>
          <family>Consolas</family>
         </font>
        </property>
        <property name="text">
         <string>Select Socket Connect Address:</string>
        </property>
       </widget>
      </item>
      <item row="3" column="1" colspan="3">
       <widget class="QComboBox" name="comboBox">
        <property name="editable">
         <bool>true</bool>
        </property>
        <item>
         <property name="text">
          <string>192.168.1.10</string>
         </property>
        </item>
        <item>
         <property name="text">
          <string>localhost</string>
         </property>
        </item>
       </widget>
      </item>
      <item row="2" column="1" colspan="3">
       <widget class="QLineEdit" name="lineEdit_2">
        <property name="font">
         <font>
          <family>Consolas</family>
         </font>
        </property>
        <property name="accessibleDescription">
         <string/>
        </property>
        <property name="inputMask">
         <string/>
        </property>
        <property name="placeholderText">
         <string>≤8个字符,多余自动删去</string>
        </property>
       </widget>
      </item>
      <item row="4" column="0">
       <layout class="QGridLayout" name="gridLayout">
        <item row="0" column="0">
         <widget class="QLabel" name="label_5">
          <property name="text">
           <string>最大超时秒数:</string>
          </property>
         </widget>
        </item>
        <item row="0" column="1">
         <widget class="QLCDNumber" name="lcdNumber">
          <property name="styleSheet">
           <string notr="true">background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, stop:0 rgba(0, 255, 223, 255), stop:0.631841 rgba(255, 255, 255, 255));
</string>
          </property>
          <property name="frameShadow">
           <enum>QFrame::Raised</enum>
          </property>
          <property name="lineWidth">
           <number>1</number>
          </property>
          <property name="midLineWidth">
           <number>0</number>
          </property>
          <property name="segmentStyle">
           <enum>QLCDNumber::Filled</enum>
          </property>
          <property name="intValue" stdset="0">
           <number>3</number>
          </property>
         </widget>
        </item>
        <item row="0" column="2">
         <spacer name="horizontalSpacer_2">
          <property name="orientation">
           <enum>Qt::Horizontal</enum>
          </property>
          <property name="sizeHint" stdset="0">
           <size>
            <width>40</width>
            <height>20</height>
           </size>
          </property>
         </spacer>
        </item>
       </layout>
      </item>
      <item row="0" column="0">
       <widget class="QLabel" name="label_6">
        <property name="styleSheet">
         <string notr="true">color:rgb(154, 154, 154);
font-size:13px</string>
        </property>
        <property name="text">
         <string>[i] 未注册的用户将自动注册</string>
        </property>
       </widget>
      </item>
     </layout>
    </widget>
   </item>
   <item row="3" column="0" colspan="3">
    <widget class="QLineEdit" name="lineEdit">
     <property name="text">
      <string>No return value.</string>
     </property>
     <property name="readOnly">
      <bool>true</bool>
     </property>
    </widget>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections>
  <connection>
   <sender>pushButton</sender>
   <signal>clicked()</signal>
   <receiver>lineEdit</receiver>
   <slot>selectAll()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>437</x>
     <y>24</y>
    </hint>
    <hint type="destinationlabel">
     <x>247</x>
     <y>57</y>
    </hint>
   </hints>
  </connection>
  <connection>
   <sender>pushButton</sender>
   <signal>clicked()</signal>
   <receiver>groupBox</receiver>
   <slot>hide()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>380</x>
     <y>139</y>
    </hint>
    <hint type="destinationlabel">
     <x>250</x>
     <y>81</y>
    </hint>
   </hints>
  </connection>
  <connection>
   <sender>horizontalSlider</sender>
   <signal>valueChanged(int)</signal>
   <receiver>lcdNumber</receiver>
   <slot>display(int)</slot>
   <hints>
    <hint type="sourcelabel">
     <x>319</x>
     <y>123</y>
    </hint>
    <hint type="destinationlabel">
     <x>378</x>
     <y>131</y>
    </hint>
   </hints>
  </connection>
 </connections>
</ui>

| 全部代码

user.pyw

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui files 'USER.ui', 'Connect.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.
import time
from PyQt5 import QtCore, QtGui, QtWidgets
import socket, sys, logging
from traceback import format_exc
from datetime import datetime
from time import sleep
from threading import Thread
from random import randint as rand
import logging  # 引入logging模块
logging.basicConfig(level=logging.DEBUG,format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')
TIMEOUT = 3
def get_host_ip() -> str:
    """get current IP address"""
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(('8.8.8.8', 80))
        ip = s.getsockname()[0]
    finally:
        s.close()
    return ip
Username = str()
bytecount = 1024
dicts = {f"103.46.128.21:51203 (公网)" : "103.46.128.21:51203",
         f"{get_host_ip()}:429 (私网)" : f"{get_host_ip()}:429",
         "EXAM-41:429          (微机室)" : "EXAM-41:429"}

def address_split(address):
    def func(ip="",port=0) -> (str, int):
        return ip,int(port)

    ip, port = func(*address.strip().split(':')[:2])
    return {"ip":ip,
            "port":port}
get_time = lambda: datetime.now().strftime('%H:%M:%S')
def threading(Daemon, **kwargs):
        thread = Thread(**kwargs)
        thread.setDaemon(Daemon)
        thread.start()
        return thread

def to_logging(command):
    def logs(*args, **kwargs):
        try:
            command(*args, **kwargs)
        except ConnectionResetError:
            if "s" in dir():
                s._connect = False
        except Exception as e:
            if "main" in dir():
                main.Show_Message(format_exc())
            else:
                logging.exception(str())
            return False
        else:
            return True
    return logs

class Socket:
    def __init__(self,Function=lambda i:None,code='utf-8'):
        self.socket = socket.socket()
        self.code = code
        self._logger = Function
        self.socket.settimeout(TIMEOUT)
        self._connect = False
    def set_func(self, f):
        self._logger = f

    def retry(self):
        del self.socket
        self.socket = socket.socket()
        self.socket.settimeout(TIMEOUT)

    def socket_connect(self):
        if hasattr(self, "_socc"):
            self.retry() #socket多次连接不同地址会出现 `OSError: [WinError 10022] 提供了一个无效的参数.`
        else:
            self._socc = True
        try:
            self.socket.connect(self.addr)
        except socket.gaierror:
            return f"获取地址信息失败.请确保{self.addr[0]}是有效地址或ipv4/ipv6"
        except socket.timeout:
            return f"连接超时({TIMEOUT}s).服务器[{self.addr[0]}:{self.addr[1]}]连接失败."
        except OverflowError:
            return f"输入的端口号为{self.addr[1]},端口号必须在0~65535间."
        except ConnectionResetError:
            pass
        except OSError as e:
            if int(self.addr[1]) == 0:
                return "[WinError 10049] 在其上下文中,该请求的地址无效"
            return str(e.args[1]).rstrip('。')
        except TypeError:
            return f"网络地址格式错误: 格式[ip:port] port必须为整型变量0~65535间."
        except:
            logging.exception(msg=str())
        else:
            return True

    def connect(self, ip = None,port:int=0000, show=lambda: None):
        if ip is None:
            assert hasattr(self,"addr"), "ip address is empty."
        else:
            self.addr = (ip, port)

        result = self.socket_connect()
        if result is True:
                show("[{}]: 连接成功".format(get_time()))
                s._connect = True
                return True
        else:
            show(f"[{get_time()}]: {result}")
            s._connect = False
            return False

    def _handler(self):
            self.socket.send(Username.encode(self.code))
            while True:
                try:
                    byte = self.socket.recv(bytecount **2)
                    if len(byte) == 0:
                            break
                    kb = len(byte) / bytecount
                    self._logger(f'{byte.decode(encoding=self.code)}                  {"<font size=1>%0.2f kb</font>" % kb}')
                except Exception as e:
                    if not type(e) == socket.timeout:
                        for n in ["","ERROR".center(20,"-")]+format_exc().split('\n')+["".center(20,"-"),""]:
                            self._logger(f"<font color='red'>{n}</font>")
                        self.socket.close()
                        return
    def run(self): #线程
        self._connect = True
        self.thread = threading(False, target=self._handler)


class Ui_Dialog(object):
    def __init__(self):
        Dialog = QtWidgets.QDialog()
        self.Dialog = Dialog
        Dialog.setObjectName("Dialog")
        Dialog.resize(532, 239)
        font = QtGui.QFont()
        font.setFamily("Consolas")
        Dialog.setFont(font)
        Dialog.setAutoFillBackground(True)
        Dialog.setStyleSheet("")
        self.gridLayout_3 = QtWidgets.QGridLayout(Dialog)
        self.gridLayout_3.setObjectName("gridLayout_3")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.label_3 = QtWidgets.QLabel(Dialog)
        self.label_3.setText("")
        self.label_3.setPixmap(QtGui.QPixmap("link.png"))
        self.label_3.setObjectName("label_3")
        self.horizontalLayout.addWidget(self.label_3)
        self.label_4 = QtWidgets.QLabel(Dialog)
        self.label_4.setObjectName("label_4")
        self.horizontalLayout.addWidget(self.label_4)
        self.gridLayout_3.addLayout(self.horizontalLayout, 0, 0, 1, 1)
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.gridLayout_3.addItem(spacerItem, 0, 1, 1, 1)
        self.progressBar = QtWidgets.QProgressBar(Dialog)
        self.progressBar.setMaximum(3)
        self.progressBar.setProperty("value", 0)
        self.progressBar.setObjectName("progressBar")
        self.gridLayout_3.addWidget(self.progressBar, 2, 0, 1, 1)
        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.gridLayout_3.addItem(spacerItem1, 2, 1, 1, 1)
        self.pushButton = QtWidgets.QPushButton(Dialog)
        self.pushButton.setObjectName("pushButton")
        self.gridLayout_3.addWidget(self.pushButton, 2, 2, 1, 1)
        self.groupBox = QtWidgets.QGroupBox(Dialog)
        self.groupBox.setObjectName("groupBox")
        self.gridLayout_2 = QtWidgets.QGridLayout(self.groupBox)
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.label_2 = QtWidgets.QLabel(self.groupBox)
        font = QtGui.QFont()
        font.setFamily("Consolas")
        self.label_2.setFont(font)
        self.label_2.setTextFormat(QtCore.Qt.AutoText)
        self.label_2.setObjectName("label_2")
        self.gridLayout_2.addWidget(self.label_2, 2, 0, 1, 1)
        self.horizontalSlider = QtWidgets.QSlider(self.groupBox)
        self.horizontalSlider.setAutoFillBackground(False)
        self.horizontalSlider.setMinimum(1)
        self.horizontalSlider.setMaximum(10)
        self.horizontalSlider.setProperty("value", 3)
        self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal)
        self.horizontalSlider.setInvertedAppearance(False)
        self.horizontalSlider.setInvertedControls(False)
        self.horizontalSlider.setTickPosition(QtWidgets.QSlider.TicksBelow)
        self.horizontalSlider.setObjectName("horizontalSlider")
        self.gridLayout_2.addWidget(self.horizontalSlider, 4, 2, 1, 1)
        self.label = QtWidgets.QLabel(self.groupBox)
        font = QtGui.QFont()
        font.setFamily("Consolas")
        self.label.setFont(font)
        self.label.setObjectName("label")
        self.gridLayout_2.addWidget(self.label, 3, 0, 1, 1)
        self.comboBox = QtWidgets.QComboBox(self.groupBox)
        self.comboBox.setEditable(True)
        self.comboBox.setObjectName("comboBox")
        self.gridLayout_2.addWidget(self.comboBox, 3, 1, 1, 3)
        self.lineEdit_2 = QtWidgets.QLineEdit(self.groupBox)
        font = QtGui.QFont()
        font.setFamily("Consolas")
        self.lineEdit_2.setFont(font)
        self.lineEdit_2.setAccessibleDescription("")
        self.lineEdit_2.setInputMask("")
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.gridLayout_2.addWidget(self.lineEdit_2, 2, 1, 1, 3)
        self.gridLayout = QtWidgets.QGridLayout()
        self.gridLayout.setObjectName("gridLayout")
        self.label_5 = QtWidgets.QLabel(self.groupBox)
        self.label_5.setObjectName("label_5")
        self.gridLayout.addWidget(self.label_5, 0, 0, 1, 1)
        self.lcdNumber = QtWidgets.QLCDNumber(self.groupBox)
        self.lcdNumber.setStyleSheet("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, stop:0 rgba(0, 255, 223, 255), stop:0.631841 rgba(255, 255, 255, 255));\n"
"")
        self.lcdNumber.setFrameShadow(QtWidgets.QFrame.Raised)
        self.lcdNumber.setLineWidth(1)
        self.lcdNumber.setMidLineWidth(0)
        self.lcdNumber.setSegmentStyle(QtWidgets.QLCDNumber.Filled)
        self.lcdNumber.setProperty("intValue", 3)
        self.lcdNumber.setObjectName("lcdNumber")
        self.gridLayout.addWidget(self.lcdNumber, 0, 1, 1, 1)
        spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem2, 0, 2, 1, 1)
        self.gridLayout_2.addLayout(self.gridLayout, 4, 0, 1, 1)
        self.label_6 = QtWidgets.QLabel(self.groupBox)
        self.label_6.setStyleSheet("color:rgb(154, 154, 154);\n"
"font-size:13px")
        self.label_6.setObjectName("label_6")
        self.gridLayout_2.addWidget(self.label_6, 0, 0, 1, 1)
        self.gridLayout_3.addWidget(self.groupBox, 1, 0, 1, 3)
        self.lineEdit = QtWidgets.QLineEdit(Dialog)
        self.lineEdit.setReadOnly(True)
        self.lineEdit.setObjectName("lineEdit")
        self.gridLayout_3.addWidget(self.lineEdit, 3, 0, 1, 3)
        self.pushButton.setEnabled(False)
        self.retranslateUi(Dialog)
        self.pushButton.clicked.connect(self._connect)
        self.horizontalSlider.valueChanged['int'].connect(self.lcdNumber.display)
        self.horizontalSlider.valueChanged['int'].connect(self.set_timeout)
        QtCore.QMetaObject.connectSlotsByName(Dialog)
        self.lineEdit_2.textChanged.connect(lambda t: self.pushButton.setEnabled(bool(t.strip())))
        self.running = False
        self.timer = threading(True, target=self.add_bar)
    def add_bar(self):
        while True:
            if self.running and self.progressBar.value() < TIMEOUT:
                self.progressBar.setValue(self.progressBar.value() + 1)
                time.sleep(1)
    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowIcon(QtGui.QIcon('login.ico'))
        Dialog.setWindowTitle(_translate("Dialog", "connect"))
        self.label_4.setText(_translate("Dialog", f"{socket.gethostname()}"))
        self.progressBar.setFormat(_translate("Dialog", "%v / %m s"))
        self.pushButton.setText(_translate("Dialog", "Connecting"))
        self.groupBox.setTitle(_translate("Dialog", "Parameter Setup"))
        self.label_2.setText(_translate("Dialog", "用户名:"))
        self.horizontalSlider.setWhatsThis(_translate("Dialog", "set time out"))
        self.label.setText(_translate("Dialog", "Select Socket Connect Address:"))
        self.comboBox.addItems(dicts.keys())
        self.lineEdit_2.setPlaceholderText(_translate("Dialog", "≤8个字符,多余自动删去"))
        self.label_5.setText(_translate("Dialog", "最大超时秒数:"))
        self.label_6.setText(_translate("Dialog", "[i] 未注册的用户将自动注册"))
        self.lineEdit.setText(_translate("Dialog", "No return value."))
        Dialog.show()
    def set_timeout(self,t):
        global TIMEOUT
        TIMEOUT = int(t)
        self.progressBar.setMaximum(TIMEOUT)
    def set_text(self, m):
        self.lineEdit.setText(QtCore.QCoreApplication.translate("Dialog", str(m)))
        self.lineEdit.update()
    @to_logging
    def _connect(self, i):
        texts = self.comboBox.currentText()
        addr = address_split(dicts.get(texts, texts))
        global TIMEOUT
        TIMEOUT = self.horizontalSlider.value()
        global Username
        Username = self.lineEdit_2.text().strip()
        self.groupBox.setEnabled(False)
        self.progressBar.setValue(0)
        self.running = True
        self.set_text("[{}]: 尝试连接服务器[{}],最大超时报错 {}s".format(datetime.now().strftime('%Y %m %d %H:%M:%S'),addr["ip"],TIMEOUT))
        if s.connect(**addr, show=self.set_text):
            global main
            main = Ui_MainWindow()
            main.show()
            def close(widget):
                sleep(1)
                widget.close()
            threading(False, target=close, args=(self.Dialog, ))
        self.groupBox.setEnabled(True)
        self.running = False

class Ui_MainWindow(object):
    def __init__(self):
        MainWindow = QtWidgets.QMainWindow()
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 619)
        font = QtGui.QFont()
        font.setFamily("Consolas")
        MainWindow.setFont(font)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.lineEdit_3 = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit_3.setReadOnly(True)
        self.lineEdit_3.setObjectName("lineEdit_3")
        self.gridLayout.addWidget(self.lineEdit_3, 7, 3, 1, 1)
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setStyleSheet("background-color:rgb(44, 176, 13);\n"
"color:rgb(255, 255, 255);\n"
"font: 200 10pt \"Consolas\";")
        self.pushButton.setObjectName("pushButton")
        self.gridLayout.addWidget(self.pushButton, 8, 6, 1, 1)
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem, 8, 5, 1, 1)
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setObjectName("label_2")
        self.gridLayout.addWidget(self.label_2, 6, 1, 1, 1)
        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem1, 8, 3, 1, 1)
        self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit_2.setReadOnly(True)
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.gridLayout.addWidget(self.lineEdit_2, 6, 3, 1, 1)
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setObjectName("label")
        self.gridLayout.addWidget(self.label, 5, 1, 1, 1)
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setCursor(QtGui.QCursor(QtCore.Qt.IBeamCursor))
        self.lineEdit.setDragEnabled(False)
        self.lineEdit.setReadOnly(True)
        self.lineEdit.setObjectName("lineEdit")
        self.gridLayout.addWidget(self.lineEdit, 5, 3, 1, 1)
        self.label_3 = QtWidgets.QLabel(self.centralwidget)
        self.label_3.setObjectName("label_3")
        self.gridLayout.addWidget(self.label_3, 7, 1, 1, 1)
        self.line = QtWidgets.QFrame(self.centralwidget)
        self.line.setFrameShape(QtWidgets.QFrame.VLine)
        self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line.setObjectName("line")
        self.gridLayout.addWidget(self.line, 5, 4, 3, 1)
        self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
        self.textEdit.setObjectName("textEdit")
        self.gridLayout.addWidget(self.textEdit, 5, 5, 3, 2)
        spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        self.gridLayout.addItem(spacerItem2, 1, 1, 1, 1)
        self.textEdit_2 = QtWidgets.QTextEdit(self.centralwidget)
        self.textEdit_2.setObjectName("textEdit_2")
        self.textEdit_2.setReadOnly(True)
        self.gridLayout.addWidget(self.textEdit_2, 0, 3, 2, 4)
        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_2.setObjectName("pushButton_2")
        self.gridLayout.addWidget(self.pushButton_2, 8, 1, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 24))
        self.menubar.setObjectName("menubar")
        self.menu = QtWidgets.QMenu(self.menubar)
        self.menu.setObjectName("menu")
        self.menulanguage = QtWidgets.QMenu(self.menu)
        self.menulanguage.setObjectName("menulanguage")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.actionsocket_connet = QtWidgets.QAction(MainWindow)
        self.actionsocket_connet.setObjectName("actionsocket_connet")
        self.actionChinese = QtWidgets.QAction(MainWindow)
        self.actionChinese.setObjectName("actionChinese")
        self.actionip_socket_gethostbyname_socket_gethostname = QtWidgets.QAction(MainWindow)
        self.actionip_socket_gethostbyname_socket_gethostname.setObjectName("actionip_socket_gethostbyname_socket_gethostname")
        self.menulanguage.addSeparator()
        self.menulanguage.addAction(self.actionChinese)
        self.menu.addSeparator()
        self.menu.addAction(self.menulanguage.menuAction())
        self.menu.addAction(self.actionip_socket_gethostbyname_socket_gethostname)
        self.menubar.addAction(self.menu.menuAction())
        self.socket_peername = s.addr[0]
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        self.MainWindow = MainWindow
        self.pushButton.clicked.connect(self.send)
        self.pushButton_2.clicked.connect(self.re_connect)
        self.connectEnabled(True)
    @to_logging
    def sendmsg(self):
        data = self.textEdit.toPlainText().strip()
        if data:
            s.socket.send(data.encode('utf8'));self.textEdit.clear()
    @to_logging
    def send(self, _):
        if hasattr(s,"_connect") and s._connect:
            if not self.sendmsg():
                QtWidgets.QMessageBox.information(self.MainWindow, 'TraceBack',f'Socket Server<{self.socket_peername}> 断开连接')
                self.connectEnabled(False)
                s._connect = False
        else:
            self.Show_Message("<font color='red'>发送异常. 未连接至服务器.请点击[重新连接服务器]按钮尝试重新连接.</font>")
    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Socket"))
        self.lineEdit_2.setText(socket.gethostname())
        self.lineEdit.setText(socket.gethostbyname(socket.gethostname()))
        self.lineEdit_3.setText(self.socket_peername)
        self.pushButton.setText(_translate("MainWindow", "send"))
        self.label_2.setText(_translate("MainWindow", "主机名:"))
        self.label.setText(_translate("MainWindow", "本地端口:"))
        self.label_3.setText(_translate("MainWindow", "连接端口:"))
        self.pushButton_2.setText(_translate("MainWindow", "重新连接服务器"))
        self.menu.setTitle(_translate("MainWindow", "设置"))
        self.menulanguage.setTitle(_translate("MainWindow", "language"))
        self.actionsocket_connet.setText(_translate("MainWindow", "socket connect"))
        self.actionChinese.setText(_translate("MainWindow", "Chinese"))
        self.actionip_socket_gethostbyname_socket_gethostname.setText(_translate("MainWindow", "ip: "+socket.gethostbyname(socket.gethostname()) ))
        s.set_func(self.Show_Message)
        s.run()
    def show(self):
        self.MainWindow.show()
    @to_logging
    def re_connect(self, _):
        self.Show_Message("[{}]: 尝试连接服务器[{}],最大超时报错 {}s".format(datetime.now().strftime('%Y %m %d %H:%M:%S'),s.addr[0],TIMEOUT))
        status = s.connect(show=self.Show_Message)
        self.connectEnabled(status)
        if status:
            s.run()
    def connectEnabled(self, status):
        self.pushButton_2.setEnabled(not status)
    def Show_Message(self, data):
        if data:
            for i in data.split('\n'):
                if i:
                    sleep(0.06 / len(data.split('\n'))) #防止信息过快使Textedit刷新空白
                    self.textEdit_2.append(i)
        self.textEdit_2.moveCursor(QtGui.QTextCursor.End)
if __name__ == "__main__":
    if len(sys.argv) > 1:
        dicts[f"{IP} (公网)"]["port"] = sys.argv[1]
    
    app = QtWidgets.QApplication(sys.argv)
    s = Socket()
    conn = Ui_Dialog()
    sys.exit(app.exec_())


| 图片链接

link.pngzmh


login.png(应该为.ico格式,直接将.png改为.ico即可,我已经换好了,但csdn平台不能传ico,所以改为了.png).
请添加图片描述

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值