The solution I'm going with, if anybody else is interested or searches for this problem:
Pyglet allows me to "push" and "pop" sets of event handlers to the window as a package (not one by one) so I figured out a really easy way to make it work: one class for each game mode contains the event handlers I need in that mode. I transition from one mode to the other by doing:
window.pop_handlers() # remove the current handlers
window.push_handlers(NewModeClass()) # add new handlers
The "return True" line in each handler ends the handling of an event. By omitting it, events can fall down to the next handler on the stack. So you could have a game mode "on top" of another game mode but not disabling it. In a city-builder game for example you might want to add a new keyboard event handler when the "build road" option is clicked, but without disabling the screen draw and map-scrolling keys in the main game mode.
A tiny demo. All this does is print a red "@" on the screen and accept key presses until ESC is pressed, then switch to "blue mode" with a blue "@" which also listens for an ESC and switches back to red mode.
import pyglet
from pyglet.window import key
pyglet.resource.path = ['resources','resources/tiles']
import modules.tiles # imports the ascii tileset and provides functions for generating colored tiles and turning text strings into tile/sprite sequences
window = pyglet.window.Window()
red_atsign = pyglet.sprite.Sprite(modules.tiles.generate_colored_tile(ord("@"),fg_color=b'\xff\x00\x00'),x=window.width//2, y=window.height//2)
blue_atsign = pyglet.sprite.Sprite(modules.tiles.generate_colored_tile(ord("@"),fg_color=b'\x00\x00\xff'),x=window.width//2, y=window.height//2)
class BlueGame(object):
def on_key_press(self,symbol,modifiers):
if(symbol==key.ESCAPE):
print("ESC pressed in BLUE mode")
window.pop_handlers()
window.push_handlers(RedGame())
else: print('Key pressed in BLUE mode')
return True
def on_draw(self):
window.clear()
blue_atsign.draw()
return True
class RedGame(object):
def on_key_press(self,symbol,modifiers):
if(symbol==key.ESCAPE):
print("ESC pressed in RED mode")
window.pop_handlers()
window.push_handlers(BlueGame())
else: print('Key pressed in RED mode')
return True
def on_draw(self):
window.clear()
red_atsign.draw()
return True
window.push_handlers(RedGame())
pyglet.app.run()
This code requires pyglet and my "tiles" module, which generates the colored @ sprites.