python线程化HTTP服务器带有图形用户界面无法正常工作

2024-09-30 20:19:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用Python编写一个简单的程序。我希望RequestHandler类和GUI类同时运行在单独的线程中,并且在RequestHandler中生成的消息经常显示在GUI中(在每个post请求中将生成一到两个消息)。下面是我的代码的简化版本:

import web
import io,json
from SocketServer import ThreadingMixIn
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
urls = ('/', 'RequestHandler')

from time import sleep
import threading
from Tkinter import *

serialdata = []
data = True
msguser = ''

class RequestHandler(BaseHTTPRequestHandler):
    def do_POST(self):
       length = int(self.headers['Content-length'])
       mylogs=self.rfile.readline(length)
       val= json.loads(mylogs)
       if val['RunningApp'].find('viber') >= 0:          
            msguser = 'viber is running on Devise ID:',val['DeviceID'],'in time:',val['timestamp']
            serialdata.append(msguser)
       if val['RunningApp'].find('telegram.messenger') >= 0:
            msguser = 'Telegram is running on Devise ID:',val['DeviceID'],'in time:',val['timestamp']
            serialdata.append(msguser)

class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
    pass

class Gui(object):
    def __init__(self):
        self.root = Tk()
        self.lbl = Label(self.root, text="")
        self.updateGUI()
        self.readSensor()

    def run(self):
        self.lbl.pack()
        self.lbl.after(1000, self.updateGUI)
        self.root.mainloop()

    def updateGUI(self):
        msg = "Data is True" if data else "Data is False"
        self.lbl["text"] = msg
        self.root.update()
        self.lbl.after(1000, self.updateGUI)

    def readSensor(self):
        self.lbl["text"] = serialdata[-1]
        self.root.update()
        self.root.after(527, self.readSensor)

if __name__ == "__main__":
    server = ThreadedHTTPServer(('X.X.X.X', 1024), RequestHandler)
    print 'Starting server, use <Ctrl-C> to stop'
    Gui().run()
    server.serve_forever()

当我运行它时,我得到错误:self.lbl["text"] = serialdata[-1] IndexError: list index out of range 而且当我给self.lbl["text"]一个静态字符串时,比如“newevent is received”

程序不作为多线程工作,并且直到GUI运行do_post永远不会运行和工作。在


Tags: textfromimportselfifisdefgui
1条回答
网友
1楼 · 发布于 2024-09-30 20:19:36

你必须在它自己的线程中运行服务器:

def main():
    server = ThreadedHTTPServer(('X.X.X.X', 1024), RequestHandler)
    print 'Starting server, use <Ctrl-C> to stop'
    server_thread = threading.Thread(target=server.serve_forever)
    server_thread.start()
    Gui().run()
    server.shutdown()

if __name__ == "__main__":
    main()

开始时serialdata为空,因此访问{}失败。因此,如果数据可用,请检查:

^{pr2}$

更好的方法是使用队列进行通信:

import threading
import json
from Queue import Queue, Empty
from SocketServer import ThreadingMixIn
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
import Tkinter as tk

class RequestHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        length = int(self.headers['Content-length'])
        mylogs = self.rfile.read(length)
        val = json.loads(mylogs)
        if 'viber' in val['RunningApp']:
            app = 'viber'
        if 'telegram.messenger' in val['RunningApp']:
            app = 'Telegram'
        self.server.queue.put('%s is running on Devise ID: %s in time: %s' % (app, val['DeviceID'], val['timestamp']))

class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
    pass

class Gui(object):
    def __init__(self, root, queue):
        self.queue = queue
        self.lbl = tk.Label(root, text="")
        self.lbl.pack()
        self.read_sensor()

    def read_sensor(self):
        try:
            self.lbl["text"] = self.queue.get_nowait()
        except Empty:
            pass
        self.lbl.after(527, self.readSensor)

def main():
    server = ThreadedHTTPServer(('X.X.X.X', 1024), RequestHandler)
    server.queue = Queue()
    print 'Starting server, use <Ctrl-C> to stop'
    server_thread = threading.Thread(target=server.serve_forever)
    server_thread.start()
    root = tk.Tk()
    gui = Gui(root, server.queue)
    root.mainloop()
    server.shutdown()

if __name__ == "__main__":
    main()

相关问题 更多 >