我用本地主機制作了簡單的程式服務器客戶端,我想與我的簡單 ui (PyQt5) 集成。這是我的代碼:
# main program
import sys
import socket
import res
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtNetwork import *
from PyQt5.QtWidgets import *
from PyQt5 import uic
from serv import Server
SERVER = socket.gethostbyname(socket.gethostname())
class MainWindow(QWidget):
def __init__(self):
QWidget.__init__(self)
uic.loadUi("serv.ui", self)
self.setGeometry(100, 50, 400, 500)
self.setWindowFlags(Qt.FramelessWindowHint)
self.setAttribute(Qt.WA_TranslucentBackground)
self.sock = self.makeServer()
self.makeConnections()
self.ipadd.setText(f'{SERVER}')
def makeServer(self):
sock = Server()
sock.start()
sock.clientReadyToRead.connect(self.onClientReadyToRead)
return sock
def makeConnections(self):
self.startButton.clicked.connect(self.onstartButtonClicked)
self.closeButton.clicked.connect(self.close)
def onClientReadyToRead(self, data):
self.messagetext.appendPlainText(data)
def onstartButtonClicked(self):
# port = self.portOpsi.currentText()
# port = int(port)
# if self.server.listen(QHostAddress(SERVER), port):
self.messagetext.appendPlainText(f"[LISTENING] Server is listening on {SERVER}\n")
# else:
# QMessageBox.critical(self, "Error", Server.errorString())
def mousePressEvent(self, QMouseEvent):
self.oldPosition = QMouseEvent.globalPos()
def mouseMoveEvent(self, QMouseEvent):
delta = QPoint(QMouseEvent.globalPos() - self.oldPosition)
self.move(self.x() delta.x(), self.y() delta.y())
self.oldPosition = QMouseEvent.globalPos()
if __name__ == "__main__":
app = QApplication(sys.argv)
app.setStyle("fusion")
w = MainWindow()
w.show()
sys.exit(app.exec_())
服務程式:
import socket
import threading
from PyQt5.QtCore import pyqtSignal, QObject
class Server(QObject):
clientReadyToRead = pyqtSignal(str)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.running = 0
def handle_client(self, conn, addr):
print(f"[NEW CONNECTION] {self.addr} connected.")
connected = True
while connected:
self.msg = self.conn.recv(1024).decode('utf-8')
self.clientReadyToRead.emit(self.msg)
print(f"[{self.addr}] {self.msg}")
if self.msg == " ":
connected = False
self.conn.close()
def start(self):
SERVER = socket.gethostbyname(socket.gethostname())
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
PORT = 5050
self.server.bind((SERVER, PORT))
self.server.listen()
print(f"[LISTENING] Server is listening on {SERVER}")
while True:
self.conn, self.addr = self.server.accept()
self.thread = threading.Thread(target=self.handle_client, args=(self.conn, self.addr))
self.thread.start()
print(f"[ACTIVE CONNECTIONS] {threading.activeCount() - 1}")
當我運行我的程式時, ui 沒有顯示但服務器準備連接并且只是在終端服務器上運行而不顯示 ui。
這是我的用戶界面,和代碼: 運行時的用戶界面
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>450</width>
<height>550</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QWidget" name="widget" native="true">
<property name="geometry">
<rect>
<x>40</x>
<y>30</y>
<width>370</width>
<height>480</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QPushButton#startButton{
background-color: rgba(0, 0, 0, 150);
color:rgba(225,225,225,210);
border-radius:3px;
}
QPushButton#startButton:hover{
background-color: rgba(20,20,20,170);
}
QPushButton#startButton:pressed{
padding-left:2px;
padding-top:2px;
background-color:rgba(20,20,20,170);
}
QPushButton#closeButton{
background-color: rgba(0, 0, 0, 0);
color:rgba(225,225,225,210);
border-radius:3px;
}
QPushButton#closeButton:hover{
background-color: rgba(0, 0, 0, 0);
}
QPushButton#closeButton:pressed{
padding-left:2px;
padding-top:2px;
background-color: rgba(0, 0, 0, 0);
}
QComboBox#portOpsi{
background-color: rgba(0, 0, 0, 150);
color:rgba(225,225,225,210);
border-radius:3px;
}
</string>
</property>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>40</x>
<y>30</y>
<width>300</width>
<height>420</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">border-image: url(:/res/res/mountains-3840x2160.jpg);
border-radius:15px;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>40</x>
<y>30</y>
<width>300</width>
<height>420</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, stop:0 rgba(0, 0, 0, 9), stop:0.494318 rgba(0, 0, 0, 50), stop:1 rgba(0, 0, 0, 75));
border-radius:15px;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>50</x>
<y>60</y>
<width>280</width>
<height>390</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-color:rgba(0,0,0,100);
border-radius:15px;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>150</x>
<y>80</y>
<width>91</width>
<height>41</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>20</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">color:rgba(255,255,255,210);</string>
</property>
<property name="text">
<string>Server</string>
</property>
</widget>
<widget class="QTextEdit" name="ipadd">
<property name="geometry">
<rect>
<x>75</x>
<y>140</y>
<width>230</width>
<height>35</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
<weight>75</weight>
<italic>false</italic>
<bold>true</bold>
<kerning>true</kerning>
</font>
</property>
<property name="styleSheet">
<string notr="true">background-color:rgba(0,0,0,0);
border:none;
border-bottom:2px solid rgba(105,118,132,255);
color:rgba(255,255,255,230);
padding-botom:7px;</string>
</property>
<property name="autoFormatting">
<set>QTextEdit::AutoNone</set>
</property>
<property name="html">
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:10pt; font-weight:600; font-style:normal;">
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8.25pt; font-weight:400;"><br /></p></body></html></string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextEditable|Qt::TextEditorInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
<property name="placeholderText">
<string>IP Address</string>
</property>
</widget>
<widget class="QComboBox" name="portOpsi">
<property name="geometry">
<rect>
<x>150</x>
<y>180</y>
<width>71</width>
<height>22</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">selection-background-color:rgba(0,0,0,255);
selection-color:(255,255,255,255);</string>
</property>
<property name="editable">
<bool>false</bool>
</property>
<item>
<property name="text">
<string>5050</string>
</property>
</item>
<item>
<property name="text">
<string>8001</string>
</property>
</item>
</widget>
<widget class="QPushButton" name="startButton">
<property name="geometry">
<rect>
<x>230</x>
<y>180</y>
<width>75</width>
<height>22</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="cursor">
<cursorShape>ArrowCursor</cursorShape>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string>Start</string>
</property>
</widget>
<widget class="QPlainTextEdit" name="messagetext">
<property name="geometry">
<rect>
<x>75</x>
<y>210</y>
<width>230</width>
<height>210</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">background-color:rgba(0,0,0,0);
border:none;
border-bottom:2px solid rgba(105,118,132,255);
color:rgba(255,255,255,230);
padding-botom:7px;</string>
</property>
</widget>
<widget class="QPushButton" name="closeButton">
<property name="geometry">
<rect>
<x>320</x>
<y>35</y>
<width>16</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="res.qrc">
<normaloff>:/res/res/close.png</normaloff>:/res/res/close.png</iconset>
</property>
<property name="iconSize">
<size>
<width>10</width>
<height>10</height>
</size>
</property>
</widget>
</widget>
</widget>
<resources>
<include location="res.qrc"/>
</resources>
<connections/>
</ui>
我只想將 ui 與服務器程式集成(在 ui 上將msg顯示為純文本等)
uj5u.com熱心網友回復:
這個問題是因為 start 方法永遠不會結束,因為它有一個 while 回圈。您可以使用 QTcpServer 或 asyncio,而不是使用執行緒和套接字。在這種情況下,我將展示第二個使用 qasync( python -m pip install qasync)的示例:
import asyncio
from functools import cached_property
from pathlib import Path
import os
import socket
import sys
from PyQt5.QtCore import QObject, Qt, pyqtSignal as Signal
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5 import uic
import qasync
CURRENT_DIRECTORY = Path(__file__).resolve().parent
SERVER = socket.gethostbyname(socket.gethostname())
class Server(QObject):
message_changed = Signal(str)
async def start(self, address="localhost", port=5050):
server = await asyncio.start_server(self.handle_client, address, port)
async with server:
await server.serve_forever()
async def handle_client(self, reader, writer):
connected = True
while connected:
message = (await reader.read(1024)).decode("utf8")
self.message_changed.emit(message)
if message == " ":
connected = False
writer.close()
class MainWindow(QWidget):
def __init__(self):
QWidget.__init__(self)
uic.loadUi(os.fspath(CURRENT_DIRECTORY / "serv.ui"), self)
self.setGeometry(100, 50, 400, 500)
self.setWindowFlags(Qt.FramelessWindowHint)
self.setAttribute(Qt.WA_TranslucentBackground)
self.makeConnections()
@cached_property
def server(self):
return Server()
def makeConnections(self):
self.startButton.clicked.connect(self.onstartButtonClicked)
self.closeButton.clicked.connect(self.close)
self.server.message_changed.connect(self.handle_message_changed)
def handle_message_changed(self, data):
self.messagetext.appendPlainText(data)
def onstartButtonClicked(self):
self.messagetext.appendPlainText(
f"[LISTENING] Server is listening on {SERVER}\n"
)
asyncio.ensure_future(self.server.start(SERVER))
def main():
app = QApplication(sys.argv)
loop = qasync.QEventLoop(app)
asyncio.set_event_loop(loop)
w = MainWindow()
w.show()
with loop:
loop.run_forever()
if __name__ == "__main__":
main()
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/317906.html
上一篇:為什么我們使用socket.io客戶端,我們只能通過socket.io服務器來制作應用程式?
下一篇:使用IPV6的UDP套接字
