Allow unhandled key and mouse-wheel events to bubble up.#552
Conversation
Fixes #550 Might have unintended consequences for existing applications, so consider it a WIP.
|
Basically LGTM. Can we try to test this and make a decision about |
|
Getting this in for 5.0.0 would mitigate the issues around potential breakage of existing code - it is a major release so some differences in behaviour are acceptable as long as we can highlight them. |
|
I fixed a logic error (the |
|
Here's a simple manual test adapted from #550 Pressing import os
import numpy as np
import logging
logging.basicConfig(level=logging.DEBUG)
from traits.api import Event, HasStrictTraits, Instance, Button
from traitsui.api import UItem, ModelView, VGroup, View
from traitsui.key_bindings import KeyBinding, KeyBindings
from chaco.api import ArrayPlotData, Plot
from enable.api import BaseTool, KeySpec, ComponentEditor
class HotkeyTool(BaseTool):
key_pressed = Event
next_key = Instance(KeySpec, args=("n",))
def normal_key_pressed(self, event):
if self.next_key.match(event):
self.key_pressed = 'next'
event.handled = True
class CustomView(ModelView):
model = Instance(HasStrictTraits, ())
dummy_button = Button('Do Nothing')
image_plot = Instance(Plot)
hotkey_tool = Instance(HotkeyTool)
def _kb_hotkey_pressed(self, info=None):
print('keybinding hotkey pressed')
def _chaco_key_pressed(self, event):
if event.new == 'next':
print('chaco hotkey pressed')
def _image_plot_default(self):
plot_data = ArrayPlotData(
intensity=np.random.randint(0, 255, size=(100, 100)))
plot = Plot(plot_data)
tool = HotkeyTool(plot)
tool.observe(self._chaco_key_pressed, 'key_pressed')
plot.tools.append(tool)
plot.img_plot('intensity')
return plot
def default_traits_view(self):
key_bindings = KeyBindings(
KeyBinding(binding1='D',
description='Hotkey',
method_name='_kb_hotkey_pressed')
)
return View(
VGroup(
UItem('dummy_button'),
# Make sure the image plot takes up some space.
UItem('image_plot', editor=ComponentEditor(), height=-400),
# Add a bunch of dummy spaces so we get a scrollbar to test the
# wheel event handling.
UItem('_'),
UItem('_'),
UItem('_'),
UItem('_'),
UItem('_'),
UItem('_'),
UItem('_'),
UItem('_'),
UItem('_'),
UItem('_'),
UItem('_'),
UItem('_'),
UItem('_'),
UItem('_'),
UItem('_'),
UItem('_'),
UItem('_'),
UItem('_'),
UItem('_'),
UItem('_'),
UItem('_'),
UItem('_'),
UItem('_'),
UItem('_'),
UItem('_'),
scrollable=True,
),
key_bindings=key_bindings,
resizable=True,
)
if __name__ == '__main__':
from traits.etsconfig.api import ETSConfig
config_dir = os.path.join(ETSConfig.application_data, 'traits')
if os.path.exists(config_dir):
for f in os.listdir(config_dir):
if f.startswith('traits_ui.'):
os.remove(os.path.join(config_dir, f))
view = CustomView()
view.configure_traits() |
|
I'll leave merging to the team working on the 5.0.0 release. |
rahulporuri
left a comment
There was a problem hiding this comment.
LGTM. I was able to use the provided manual script to verify that this change works as expected on pyqt and pyqt5 on windows.
@rkern Can you make time to add a regression test in this PR? I'm not sure how easy/difficult it will be to add the test.
|
Thanks @rkern . I resolved the merge conflicts. Merging. |
Fixes #550
Might have unintended consequences for existing applications, so consider it a WIP for testing.
When a Qt widget receives a
QKeyEventthat it does not handle, it is supposed to call theignore()method to allow the event to bubble up to the parent widget.KeyPressandKeyReleaseevents areacceptedby default, so if not explicitly ignored, the in-focus Enable widget will swallow all of theseQKeyEvents.We should consider doing the same for
wheelEvent(), asQWheelEvents have the same semantics. This has led to issues when Enable components are embedded in a scrolled group.