2

Я пытаюсь создать простое настольное приложение, используя PyQt, который запускает SimpleHTTPServer при нажатии кнопки запуска сервера. Я пробовал использовать потоки (как потоки python, так и Qthread), и понимаю, что это невозможно, поскольку оно сталкивается с проблемами с GIL. Вот кодPyQt SimpleHTTPServer: GUI зависает на стартовом сервере

def btn_startserver_clicked(self): 
    server_thread=threading.Thread(target=start_server()) 
    server_thread.start() 


def start_server(): 
    #to get server's IP 
    host=([(s.connect(('8.8.8.8', 80)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]) 
    start=8000 
    end=56999 
    PORT = random.randint(start,end) 
    print host,":",PORT 
    httpd=ThreadedServer(("",PORT), SimpleHTTPServer.SimpleHTTPRequestHandler) 
    httpd.handle_request()` 

Я попытался создать еще один процесс, но произошло то же самое. Кроме того, если я создаю другой процесс, каждое окно будет всплывать при каждом запросе.

def btn_startserver_clicked(self): 
    if __name__=='__main__': 
     server_process=Process(target=start_server()) 
     server_process.start() 

Есть ли способ обойти это? Я считаю, что использование многопроцессорности - правильный подход, но я новичок в этом и не могу понять, почему он все еще зависает.

Благодаря

ответ

2

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

server_thread=threading.Thread(target=start_server) 

Обратите внимание, что я бросаю скобки на start_server иначе код ждет start_server() окончания выполнения перед созданием threading.Thread объекта, и использует возвращаемое значение start_server() в качестве значения для target атрибут.

Окончательное предложение, вы должны действительно сохранить созданную нить как self.server_thread, чтобы предотвратить сбор мусора.

+0

Спасибо. Это была неосторожная ошибка. Но как это все еще выполняется, если python может выполнять только один поток за раз? Или я понял это неправильно? – raksh93

+0

@ raksh93 Python переключается между потоками. Таким образом, многопоточность не обеспечивает производительности, однако она помогает сохранять такие функции, как графические интерфейсы. –

0

Не совсем уверен, что вы пытаетесь сделать, но это может помочь вам начать работу:

import sys 
from urllib.request import urlopen 
from http.server import HTTPServer, SimpleHTTPRequestHandler 
from PyQt4 import QtCore, QtGui 

HOST, PORT = '127.0.0.1', 12345 

class HttpDaemon(QtCore.QThread): 
    def run(self): 
     self._server = HTTPServer((HOST, PORT), SimpleHTTPRequestHandler) 
     self._server.serve_forever() 

    def stop(self): 
     self._server.shutdown() 
     self._server.socket.close() 
     self.wait() 

class Window(QtGui.QWidget): 
    def __init__(self): 
     super(Window, self).__init__() 
     self.button = QtGui.QPushButton('Start', self) 
     self.button.clicked.connect(self.handleButton) 
     layout = QtGui.QVBoxLayout(self) 
     layout.addWidget(self.button) 
     self.httpd = HttpDaemon(self) 

    def handleButton(self): 
     if self.button.text() == 'Start': 
      self.httpd.start() 
      self.button.setText('Test') 
     else: 
      urlopen('http://%s:%s/index.html' % (HOST, PORT)) 

    def closeEvent(self, event): 
     self.httpd.stop() 

if __name__ == '__main__': 

    app = QtGui.QApplication(sys.argv) 
    window = Window() 
    window.show() 
    sys.exit(app.exec_()) 
+0

Спасибо. Я пытаюсь создать простое приложение для совместного использования файлов в домашней сети – raksh93

Смежные вопросы