2017-06-16 70 views
0

我有一个python脚本启动一个基本的web服务器,并响应某些输入,工作正常。我也有Windows系统托盘图标工作(显示一个ico文件) - 但目前脚本似乎在显示系统图标时阻塞。Python - 启动HTTP服务器并设置Windows系统托盘

我只想让一个python HTTP服务器侦听,并在脚本运行时显示系统托盘图标 - 这已经是一个隐藏的python窗口,我想知道它是否因任何原因失败。

我是否需要启动两个单独的线程?还是有更好的方法来做到这一点?这里是我的原代码(节选只):

hover_text = "My Tray Icon Text" 
def hello(sysTrayIcon): print "Hello World." 
def simon(sysTrayIcon): print "Hello Simon." 
def switch_icon(sysTrayIcon): 
    pass 
menu_options = (('Say Hello', None, hello), 
       ('Switch Icon', None, switch_icon), 
       ('A sub-menu', None, (('Say Hello to Simon', None, simon), 
               ('Switch Icon', None, switch_icon), 
              )) 
       ) 
def bye(sysTrayIcon): 
    print ("Server stopped by user") 
    sys.exit() 
    # server.shutdown() 

print("setting system tray icon") 
SysTrayIcon("hazard.ico", hover_text, menu_options, on_quit=bye, default_menu_index=1) 

print("starting server") 


#local only 
#server = HTTPServer(('localhost', 9006), GetHandler) 

#listen on all interfaces 
server = HTTPServer(('0.0.0.0', 9006), GetHandler) 

#print 'Starting server, use to stop' 
server.serve_forever() 

我试图移动服务器启动时系统托盘图标之前的设置是这样的:

thread = threading.Thread(target = server.serve_forever()) 

,但随后在服务器启动一块块,无图标已设置。

我也试过这个

from SocketServer import ThreadingMixIn 

class ThreadingServer(ThreadingMixIn, HTTPServer): 
    pass 

srvr = ThreadingServer(('0.0.0.0', 9006), GetHandler) 
srvr.serve_forever() 

reference ,但它仍然在块服务器件。

我是否应该使用多处理而不是多线程?该脚本相当小&琐碎。

回答

0

我假设SysTrayIcon()调用被阻止(不熟悉此功能并且代码示例中缺少提供模块)。

如果是这样,那么一种解决方案是按照您的尝试在单独的线程中启动服务器。 需要注意的一件事是,当一个线程正在启​​动时,该函数的参考应该被传递给Thread()target

所以你需要的代码是这样的:

server_thread = threading.Thread(target=server.serve_forever) 
server_thread.start() 

而不是调用的方法。在代码示例中,正在调用server.serve_forever,因此该块(该方法永远阻止接受和处理HTTP请求)。

即使您从SocketServer中选择ThreadingMixIn,也应该在单独的线程中调用serve_foreverThreadingMixIn允许服务器在不同线程中为每个HTTP请求提供服务,但对serve_forever的调用仍将阻止当前线程。

此外,我会建议想想一个正确的方法来停止服务器线程(例如使用threading.Event),当你的应用程序要停止。或者,在另一个主题中调用SysTrayIcon()很简单:

threading.Thread(target=SysTrayIcon, args=("hazard.ico", hover_text, menu_options), kwargs=dict(on_quit=bye, default_menu_index=1)) 
+0

感谢您的回答。道歉,以下是托盘图标代码的参考链接:http://www.brunningonline.net/simon/blog/archives/SysTrayIcon.py.html 我已经使用了函数的引用,但它仍然阻塞在myThread1上。开始() 我会继续玩这个,看看我能做些什么。 是的不用担心sys,退出只是一个占位符。 ;-) – TheDavil

+0

我试过你的第二个编辑,另一个线程调用systray图标。他们都因为某种原因而阻止。我有一种感觉,我对这一切都是错误的,但很快就会发现它 – TheDavil

+0

我没有使用Python Win32 API的经验,有些GUI框架需要使用主线程进行某些操作。你可能会发现这样的技巧。一般情况下,如果您检测到阻塞调用并在线程中启动它们,则主线程将不会阻塞(除非线程是忙碌循环,从而导致其他线程无法正确处理)。 – farzad

相关问题