Tahmid Faisal
Tahmid Faisal

Reputation: 113

Qt and Web server app OSError: [WinError 10038] An operation was attempted on something that is not a socket

I was creating a pyqt app which will start a web server and view it by QWebEngineView.

It uses http.server to create the webserver.

It also uses multithreading to create the server.

Here is my code of the app.

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()

But It outputs an error:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\threading.py", line 954, in _bootstrap_inner
    self.run()
  File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\threading.py", line 892, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\socketserver.py", line 232, in serve_forever
    ready = selector.select(poll_interval)
  File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\selectors.py", line 324, in select
    r, w, _ = self._select(self._readers, self._writers, [], timeout)
  File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\selectors.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

Upvotes: 1

Views: 257

Answers (1)

eyllanesc
eyllanesc

Reputation: 244132

The problem is that you are starting the connection and instantly you are closing it. The logic is to keep it open while the eventloop is running:

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()

Upvotes: 1

Related Questions