问题描述
我有2个课程:
- 服务器
- 虚拟课程
我需要能够从Blender之类的程序中运行此程序。由于 server 需要不断侦听任何请求,因此我需要在单独的线程中运行它,否则它将阻塞主UI。 虚拟需要在主线程中运行。
服务器收到请求后,它需要发出一个信号,该信号将被虚拟捕获。但是,无论我如何尝试,我似乎都无法捕捉到来自服务器的信号。
以下是一些无需Blender即可运行的示例代码:
服务器和虚拟类
import wsgiref.simple_server
import json
from pyside2.QtCore import *
class DummyClass(QObject):
def __init__(self):
super(DummyClass,self).__init__()
print("Started the dummy")
def catch_dummy_signal(self,name,dictionary):
print(name)
print(dictionary)
print("I CAUGHT THE DUMMY SIGNAL")
class Server(QObject):
DUMMY_SIGNAL = Signal(str,dict)
def __init__(self):
super(Server,self).__init__()
def start_listening(self):
simple_server = wsgiref.simple_server.make_server("127.0.0.1",65500,self.process_request)
print(simple_server.server_address)
while True:
simple_server.handle_request()
def process_request(self,environ,start_response):
print("Got request")
status = "200 OK"
headers = [("Content-type","text/plain")]
start_response(status,headers)
request_body_size = int(environ.get('CONTENT_LENGTH',0))
request_body = environ['wsgi.input'].read(request_body_size)
query = json.loads(request_body)
print("Emitting dummy signal")
self.DUMMY_SIGNAL.emit("Luke Skywalker",{"occupation": "Jedi Knight"})
command_result = {"query": query}
return [json.dumps(command_result).encode()]
if __name__ == '__main__':
server = Server()
dummy = DummyClass()
server.DUMMY_SIGNAL.connect(dummy.catch_dummy_signal)
thread = QThread()
server.movetoThread(thread)
thread.started.connect(server.start_listening)
thread.start()
# running an endless loop here,otherwise the program ends. This endless loop will not be used when running it inside a program like Blender
while True:
pass
此客户端代码可用于调用向发出DUMMY_SIGNAL的服务器的请求,以供虚拟捕获:
import requests
url = "http://127.0.0.1:65500"
payload = {"data": "This is important data!"}
response = requests.post(url,json=payload).json()
print(response)
服务器的输出如下:
Started the dummy
('127.0.0.1',65500)
got request
Emitting dummy signal
127.0.0.1 - - [01/Oct/2020 16:19:33] "POST / HTTP/1.1" 200 46
客户端的输出如下:
{'query': {'data': 'This is important data!'}}
从服务器的输出中可以看到,catch_dummy_signal
的打印语句未显示。因此,我必须假设该函数从未被调用。
如何通过向服务器发出请求来触发catch_dummy_signal
?
解决方法
仅当存在Qt eventloop时,信号才起作用,因为它是一种传输手段,在您的情况下,使用QCoreApplication就足够了:
if __name__ == "__main__":
app = QCoreApplication([])
server = Server()
dummy = DummyClass()
server.DUMMY_SIGNAL.connect(dummy.catch_dummy_signal)
thread = QThread()
server.moveToThread(thread)
thread.started.connect(server.start_listening)
thread.start()
app.exec_()