sharkyenergy
sharkyenergy

Reputation: 4173

PyQt5 - Move QTcpServer to subprocess

I am trying to run a QtcpServer on a different thread or even better on a subprocess in python using PyQt5.

Running it on a different QThread I get this error as soon as the server tries to send something to the client:

QObject: Cannot create children for a parent that is in a different thread. (Parent is QNativeSocketEngine(0x295023f7c50), parent's thread is QThread(0x29501ed7e30), current thread is QThread(0x2957feaffb0)

After some googeling i found that I should not run a QTcpServer on a different thread. So I decided to run it as a separate subprocess, so it should have its own thread where everything is initialized and should work... at least in my own theory.. The server starts up alright, it prints out the message "listening for connections on port 2001" but I cannot connect with my client.

Connecting to 127.0.0.1 ... TCP connection error :10061

Any help is greatly appreciated...

here is my code:

main.py:

import sys import serverSub 
from PyQt5 import QtWidgets, QtCore 
from PyQt5.QtCore import * 
from PyQt5.QtGui import * 
from PyQt5.QtWidgets import * 
from PyQt5.uic import loadUi


class UiMainWindow(QMainWindow):

    serverSp = serverSub.TcpSubprocess()
    def __init__(self):
        super(UiMainWindow, self).__init__()
        self.serverSp.start_server()
        self.show()


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = UiMainWindow()
    sys.exit(app.exec_())

serverSub.py:

import subprocess
from PyQt5.QtCore import *

class TcpSubprocess(QObject):
# Start the server as a subprocess
    p = subprocess.Popen
    def start_server(self):
        command = ['python', 'server2.py']
        self.p = subprocess.Popen(command)

server2.py:

import sys
from PyQt5.QtCore import *
from PyQt5.QtNetwork import QHostAddress, QTcpServer
    
class Server(QObject):
    def __init__(self):
        QObject.__init__(self)
        self.TCP_LISTEN_TO_PORT = 2001
        self.server = QTcpServer()
        self.server.newConnection.connect(self.on_new_connection)
        self.start_server()
        self.socket = None

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("server exited..")

    def on_new_connection(self):
        while self.server.hasPendingConnections():
            self.set_socket(self.server.nextPendingConnection())

    def start_server(self):
        if self.server.listen(
                QHostAddress.Any, self.TCP_LISTEN_TO_PORT
        ):
            print("Server is listening on port: {}".format(self.TCP_LISTEN_TO_PORT))
        else:
            print("Server couldn't wake up")
            
    def set_socket(self, socket):
        self.socket = socket
        self.socket.connected.connect(self.on_connected)
        self.socket.disconnected.connect(self.on_disconnected)
        self.socket.readyRead.connect(self.on_ready_read)
        print("Client connected from Ip %s" % self.socket.peerAddress().toString())

    def on_ready_read(self):
        msg = self.socket.readAll()
        msg_txt = str(msg, 'utf-8').strip()
        messages = msg_txt.split("\r")
        segments = messages[0].split(",")
        

        if segments[0] == "STA":
            status = int(segments[1])
            # send back OK message
            out = 'OK\r'
            self.socket.write(bytearray(out, 'ascii'))
            
    def on_connected(self):
        print("Client connected")


    def on_disconnected(self):
        print("Client disconnected")

if __name__ == '__main__':
    Server()

Upvotes: 0

Views: 72

Answers (0)

Related Questions