Я пытаюсь создать небольшое приложение на Python, где простой веб-сервер работает в фоновом режиме, и вы можете использовать графический интерфейс для отправки различных сообщений.
Я использую PyQt5 и Python3.6,и мне удалось передать данные из рабочего потока в графический интерфейс, но я не знаю, как это сделать наоборот.
Вот скелет моего кода:
MainWindow:
class Ui_MainWindow(object):
def __init__(self):
super().__init__()
self.input = True
# 1 - create Worker and Thread inside the Form
self.obj = WebServer.WebServer(self.input) # no parent!
self.thread = QtCore.QThread() # no parent!
# 2 - Connect Worker`s Signals to Form method slots to post data.
self.obj.dataReady.connect(self.onDataReady)
# 3 - Move the Worker object to the Thread object
self.obj.moveToThread(self.thread)
# 4 - Connect Worker Signals to the Thread slots
self.obj.finished.connect(self.thread.quit)
# 5 - Connect Thread started signal to Worker operational slot method
self.thread.started.connect(self.obj.startServer)
# 6 - Start the thread
self.thread.start()
# 7 - Start the form
self.setupUi()
def setupUi(self):
# Set up the GUI
#...
self.MainWindow.show()
def onDataReady(self, data):
# Data received from working thread
# Do stuff...
def on_click_set2(self):
self.input = not self.input
print(self.input)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
ui = Ui_MainWindow()
sys.exit(app.exec_())
WebServer:
class WebServer(QObject):
finished = pyqtSignal()
dataReady = pyqtSignal(dict)
def __init__(self, input):
super().__init__()
self.input = input
@pyqtSlot()
def startServer(self): # A slot takes no params
# self.loop = asyncio.get_event_loop()
self.loop = asyncio.new_event_loop()
asyncio.set_event_loop(self.loop)
coro = asyncio.start_server(self.handle_update, '192.168.2.1', 8888, loop=self.loop)
self.server = self.loop.run_until_complete(coro)
# Serve requests until Ctrl+C is pressed
print('Serving on {}'.format(self.server.sockets[0].getsockname()))
try:
self.loop.run_forever()
except KeyboardInterrupt:
pass
self.finished.emit()
async def handle_update(self, reader, writer):
data = await reader.read(100)
message = data.decode()
addr = writer.get_extra_info('peername')
print(f'Received: {message} from {addr}')
if self.input:
print("Input is True")
else:
print("Input is False")
reply = self.input
print(f'Send: {reply}')
writer.write(str(reply).encode())
await writer.drain()
print("Close the client socket")
writer.close()
self.dataReady.emit(reply)
Так, например, я хочу передать ввод в поток, и если я делаю как выше (очевидно), ввод всегда остается начальным значением и не изменится в потоке, когда я нажму кнопку в графическом интерфейсе.
Как я могу сделать так, чтобы значение ввода обновлялось всякий раз, когда я нажимал кнопку (поэтому передача значения потоку из GUI во время выполнения)?Я предполагаю, что это похоже на переход от потока к графическому интерфейсу, поэтому излучение сигнала из графического интерфейса и подключение к нему по протектору, но я не знаю, как найти ссылку на графический интерфейс из рабочего потока.
Так какой совет, как это сделать?И, конечно, приветствуется любой другой вклад, касающийся кода или подхода к решению сервера приложений / фона!Заранее спасибо за помощь!
ОБНОВЛЕНИЕ:
Может быть, не совсем понятно, каков был мой вопрос, поэтому вот он:
Как я могу отправитьзначение из потока GUI в рабочий поток, в то время как оба они работают параллельно? (Если приведенный выше код имеет какой-либо смысл для вас, используйте это в качестве примера, иначе будет полезен общий пример)