【问题标题】:wxPython handling SIGTERM / SIGINTwxPython 处理 SIGTERM / SIGINT
【发布时间】:2016-11-09 18:51:23
【问题描述】:

我有一个 wxPython 应用程序。我希望它响应 SIGTERM 和 SIGINT 就像单击“关闭”按钮一样。但是,当我使用signal.signal(signal.SIGTERM, exit_handler) 绑定信号时,它们仅在事件以图形方式发送到主应用程序(单击按钮、打开菜单等)后才会执行。如何避免这种情况并在捕获事件后立即执行句柄?

相关代码部分:

class MyFrame(wx.Frame):
    def __init__(self, parent, title):
        # ...
        self.Bind(wx.EVT_CLOSE, self.signal_handler)
        signal.signal(signal.SIGTERM, self.signal_handler)
        signal.signal(signal.SIGINT, self.signal_handler)

# ...

app = wx.App(redirect=False, clearSigInt=False)
frame = MyFrame(None, "Hello World")
app.MainLoop()

即使信号调用被移到任何函数之外并在任何 wx 调用之前执行,也会发生这种情况。

【问题讨论】:

    标签: python python-2.7 wxpython signals


    【解决方案1】:

    一种方法是添加一个“计时器”来伪造事件。

    import wx
    import signal, os
    
    def signalUSR1_handler(sig,frame):
        print ("Signal Caught")
    
    class ExampleFrame(wx.Frame):
        def __init__(self, parent):
            wx.Frame.__init__(self, parent)
            pid_no = str(os.getpid())
            panel = wx.Panel(self)
            self.quote1 = wx.StaticText(panel, label="Test signal with timer", pos=(20, 30))
            self.quote2 = wx.StaticText(panel, label="Send this process a USR1 signal", pos=(20, 50))
            self.quote3 = wx.StaticText(panel, label="kill -s USR1 "+pid_no, pos=(20, 70))
            self.button = wx.Button(panel, -1, "Click", pos=(20,90))
            self.button.Bind(wx.EVT_BUTTON, self.OnPress)
            self.timer = wx.Timer(self)
            self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
            self.timer.Start(1000)
            self.Show()
        def OnPress(self, event):
            print ("Button Pressed")
        def OnTimer(self, event):
            return
    app = wx.App()
    ExampleFrame(None)
    signal.signal(signal.SIGUSR1,signalUSR1_handler)
    app.MainLoop()
    

    【讨论】:

    • 为了帮助您理解它为什么会这样工作:IIRC,Python 中的信号在发生时被捕获,但仅在执行 Python 代码时处理。因此,如果信号在程序处于 MainLoop 等待事件时发生,那么将不会对它做任何事情,直到某些事情导致控制返回到 Python 代码(例如将事件分派到 Python 代码中的处理程序)。所以使用计时器如上所述是确保控制离开 MainLoop 并定期进入 Python 代码以便可以调用信号处理程序的一种方法。
    • @RobinDunn 我真的应该在我的回答中解释一下,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-15
    • 2011-09-21
    • 2020-07-03
    • 2011-02-27
    • 2021-09-23
    • 2011-06-16
    • 1970-01-01
    相关资源
    最近更新 更多