I've been trying to open my kivy app a second time after closing the window (because it's a tray app). However I run into an exception, when closing the App using the Esc key and then re-running the app.
This error doesn't happen, when I close the window by clicking the cross in the window bar instead.
Here is some code example reproducing the issue:
from time import sleep
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.widget import Widget
class MyApp(App):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.my_window = Widget()
def build(self):
return self.my_window
def on_stop(self):
Window.hide()
if __name__ == '__main__':
Window.top = 30
app = MyApp()
app.run()
# Restart the App after one second
sleep(1)
Window.show()
app.run()
When closing the first window using the esc key, the second window does not appear. Instead I receive this:
Connected to pydev debugger (build 223.8836.43)
[INFO ] WM_MotionEventProvider <kivy.input.providers.wm_touch.WM_MotionEventProvider object at 0x0000016E2A86E790>
[INFO ] WM_MotionEventProvider <kivy.input.providers.wm_touch.WM_MotionEventProvider object at 0x0000016E2A8816D0>
[ERROR ] [Base ] No event listeners have been created
[ERROR ] [Base ] Application will leave
python-BaseException
Is there some way to avoid this problem?
(This happens in kivy2.3.0 on python3.11 and windows11)
This is the full solution I went with, in case anyone else comes across this issue. I've first disabled the built-in escape as suggested by @nigh_anxiety. Then added my own method to close the window.
from time import sleep
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.widget import Widget
from kivy.config import Config
Config.set('kivy', 'exit_on_escape', '0') # Disable the built-in feature
class MyApp(App):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.my_window = Widget()
self._keyboard = Window.request_keyboard(self._keyboard_closed, self)
self._keyboard.bind(on_key_down=self._on_keyboard_down)
def _keyboard_closed(self):
self._keyboard.unbind(on_key_down=self._on_keyboard_down)
self._keyboard = None
def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
_, key = keycode
if key == 'escape':
app.stop()
def build(self):
return self.my_window
if __name__ == '__main__':
Window.top = 30
app = MyApp()
app.run()
Window.hide()
# Restart the App after one second
sleep(1)
Window.show()
app.run()