2016-07-07 1 views
1

У меня есть приложение wxPython. Я хочу, чтобы он отвечал на SIGTERM и SIGINT так же, как если бы нажала кнопка «закрыть». Однако, когда я связываю сигналы с помощью signal.signal(signal.SIGTERM, exit_handler), они выполняются только после того, как событие будет отправлено в основное приложение графически (нажатие кнопки, меню открытия и т. Д.). Как я могу избежать этого и выполнить дескрипторы, как только событие будет поймано?wxPython обработка SIGTERM/SIGINT

Соответствующие части кода:

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 вызовов.

ответ

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() 
+1

Чтобы помочь вам понять, почему это работает так: сигналы IIRC, сигналы на Python пойманы, когда они происходят, но обрабатываются только при выполнении кода Python. Поэтому, если сигнал происходит, когда программа находится в MainLoop, ожидающем события, тогда ничего не будет сделано, пока что-то не приведет к тому, что элемент управления вернется к коду Python (например, отправка события обработчику в коде Python). Таким образом, используя таймер как описано выше, является одним из способов гарантировать, что элемент управления покидает MainLoop и периодически переходит в код Python, чтобы обработчики сигналов могли быть вызваны. – RobinDunn

+0

@RobinDunn Я действительно должен был объяснить это в своем ответе, спасибо! –

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

  • Нет связанных вопросов^_^