Ошибка ОС приложений Qt и веб-сервера: [Ошибка WinError 10038] Была предпринята операция над чем-то, что не является сокетом

#python #python-3.x #multithreading #pyqt5 #python-sockets

Вопрос:

Я создавал приложение pyqt, которое запустит веб-сервер и просмотрит его с помощью QWebEngineView.

Он использует http.server для создания веб-сервера.

Он также использует многопоточность для создания сервера.

Вот мой код приложения.

 import sys
import threading
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import QUrl
from PyQt5.QtWebEngineWidgets import QWebEngineView

from http.server import BaseHTTPRequestHandler, HTTPServer
import threading


class Window(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        self.setWindowTitle("Medicine")
        self.setWindowIcon(QIcon("icon.png"))
        layout = QVBoxLayout()
        self.setLayout(layout)
        web = WebPage()
        layout.addWidget(web)

class WebPage(QWebEngineView):
    def __init__(self):
        QWebEngineView.__init__(self)
        self.load(QUrl("http://127.0.0.1:8000"))
        
app = QApplication(sys.argv)


class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type','text/html')
        self.end_headers()

        message = "Hello, World!"
        self.wfile.write(bytes(message, "utf8"))

with HTTPServer(('', 8000), Handler) as server:
    t = threading.Thread(target=server.serve_forever)
    t.start()


def startapp():
    screen = Window()
    screen.show()
    sys.exit(app.exec_())

startapp()
 

Но он выдает ошибку:

 Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:UsersUserAppDataLocalProgramsPythonPython39libthreading.py", line 954, in _bootstrap_inner
    self.run()
  File "C:UsersUserAppDataLocalProgramsPythonPython39libthreading.py", line 892, in run
    self._target(*self._args, **self._kwargs)
  File "C:UsersUserAppDataLocalProgramsPythonPython39libsocketserver.py", line 232, in serve_forever
    ready = selector.select(poll_interval)
  File "C:UsersUserAppDataLocalProgramsPythonPython39libselectors.py", line 324, in select
    r, w, _ = self._select(self._readers, self._writers, [], timeout)
  File "C:UsersUserAppDataLocalProgramsPythonPython39libselectors.py", line 315, in _select
    r, w, x = select.select(r, w, w, timeout)
OSError: [WinError 10038] An operation was attempted on something that is not a socket
 

Ответ №1:

Проблема в том, что вы запускаете соединение и мгновенно закрываете его. Логика заключается в том, чтобы держать его открытым во время работы eventloop:

 import sys
import threading

from PyQt5.QtCore import QUrl
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget
from PyQt5.QtWebEngineWidgets import QWebEngineView

from http.server import BaseHTTPRequestHandler, HTTPServer


class Window(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.setWindowTitle("Medicine")
        self.setWindowIcon(QIcon("icon.png"))
        layout = QVBoxLayout(self)
        web = WebPage()
        layout.addWidget(web)


class WebPage(QWebEngineView):
    def __init__(self):
        QWebEngineView.__init__(self)
        self.load(QUrl("http://127.0.0.1:8000"))


class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.end_headers()

        message = "Hello, World!"
        self.wfile.write(bytes(message, "utf8"))


def startapp():
    ret = 0
    app = QApplication(sys.argv)

    with HTTPServer(("", 8000), Handler) as server:
        t = threading.Thread(target=server.serve_forever, daemon=True)
        t.start()

        screen = Window()
        screen.show()

        ret = app.exec_()
    sys.exit(ret)


startapp()