如何解决wxPython 托盘图标:从另一个线程或函数调用退出
我有一个 wxPython TaskbarIcon 类,除了托盘图标之外没有其他父窗口,因为它作为一种后台进程运行。下面提供的是一个完整的工作示例 -->
import subprocess as sp
import wx.adv
from threading import Thread,Event
import os,signal
####### Create Tray Icon #######
def create_menu_item(menu,label,func):
item = wx.MenuItem(menu,-1,label)
menu.Bind(wx.EVT_MENU,func,id=item.GetId())
menu.Append(item)
return item
class TaskBarIcon(wx.adv.TaskBarIcon):
def __init__(self,frame):
self.frame = frame
super(TaskBarIcon,self).__init__()
self.set_icon(TRAY_ICON)
self.Bind(wx.adv.EVT_TASKBAR_LEFT_UP,self.Run_Now)
self.Bind(wx.adv.EVT_TASKBAR_RIGHT_DCLICK,self.on_exit)
def CreatePopupMenu(self):
menu = wx.Menu()
create_menu_item(menu,'Open Log_File',self.GoTo_Log)
menu.AppendSeparator()
create_menu_item(menu,'Exit',self.on_exit)
return menu
def set_icon(self,path):
icon = wx.Icon(path)
self.SetIcon(icon,TRAY_TOOLTIP)
def GoTo_Log(self,event):
print("Log File will be Opened -- :)\n")
# sp.Popen(["explorer.exe",LogFile])
def Run_Now(self,event):
# Run my task
print("Running Now...")
def on_exit(self,event):
print('exiting . . . ')
wx.CallAfter(self.Destroy)
self.frame.Close(True)
self.RemoveIcon()
os.kill(pid,signal.SIGBREAK)
class App(wx.App):
def OnInit(self):
frame= wx.Frame(None)
self.SetTopWindow(frame)
sysTray= TaskBarIcon(frame)
print("Moved to Sys Tray !\n")
return True
################################
if __name__ == '__main__':
app = App(False)
app.MainLoop()
我想在这里添加在按键(例如“F7”)上退出(关闭 SysTray)的便利。我首先决定使用一种检测按键的方法绑定 EVT_KEY_DOWN,然后调用 on_exit。但是我花了一段时间才意识到 TaskBarIcon 不支持 EVT_KEY_DOWN,因为没有父窗口! 下面是我检测按键('F7')的函数:
import keyboard,os,signal
def DetectEND(Force_END = False):
#Long Press "F7" button to Terminate this Background Application
if keyboard.is_pressed('f7') or Force_END:
print("'f7' press detected | Ending Service ...")
# cleanHandlers(B_Log) # OR some other cleaning activities before quitting
os.kill(pid,signal.SIGBREAK) # Using this instead of quit() since this would not run in the main thread !
return True
return False
基本上,然后我只是尝试将上述内容用作 线程 来查找按键,当返回 True 时...想与 TaskBarIcon 实例通信调用 self.on_exit 方法,但这里也无法弄清楚如何在没有事件绑定器的情况下进行通信!
另外,我是这个 wxpython 的新手,所以......对 wxpython 的“MainLooping”没有任何正确的想法......否则会设置一个 threading.Event (),使 DetectEND func 在 True 时设置事件,然后在 TaskBarIcon 类中检查 Event.is_set(),但我知道这个循环与处理简单的 while True 循环有很大不同!!
除了上面提到的方法......我也尝试了其他方法,比如来自 DetectEND func 本身的 wx.CallAfter() 和一些全局热键方法,但是在这种情况下没有一个有效,或者有时我无法弄清楚实现。
谢谢你 - 一直陪着我!
最后会感谢任何能够完成工作的方法......而且特定于 Windows 的方法甚至会太棒了。
我刚刚想到的其他一些方法——比如不涉及线程(或)将 Key_down 事件绑定到 TaskBarIcon 的方法(或)CallAfter 调用 self 的解决方法.on_exit 来自另一个非类函数的方法...(无所谓)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。