I am continuing to have immense trouble receiving EVT_CHAR events on my custom control. After searching the internet for days, I am at a loss as to why I am not getting the events.
I understand that questions pertaining to EVT_CHAR are plenty - I have read through quite a number of them, however none of the solutions provided seem to work. I have ensured the following:
- The custom control has focus
- I am binding directly on the source of the event (the custom control)
- My custom control has wx.WANTS_CHARS. I have tried removing it, with no perceivable difference.
I have tried with and without wx.WANTS_CHARS on the frame.
I have tried binding to the frame and the control, both with and without the source parameter pointing to each. There are no other keyboard-related event bindings, however I do have accelerators configured, as per the code below.
I have also tried to extend upon wx.TextEntry. One possibility I was attempting to chase down is that the custom control will not receive these events as it does not appear to be a text entry control, and that the event only fires on non-readonly/editable controls. I had no luck figuring this out.
Version Information:
I am testing this on both Python 3.7, and most often on 3.6.
wxPython version 4.0.3
Windows 10.1709 Enterprise
The following is the code snippets from my frame class, responsible for constructing the GUI and listening on these events. I have also included the (currently useless) event handler for EVT_CHAR.
def do_create_gui(self):
classname = self.__class__.__name__
app = wx.App()
AppTitle = "%s: %s" % (self._comms.port, classname)
size = wx.Size(700, 450)
frame = wx.Frame(None, title=AppTitle, size=size)
panel = wx.Panel(frame)
panelSizer = wx.BoxSizer(wx.VERTICAL)
sizer = wx.BoxSizer(wx.VERTICAL)
# Configure Menu
fileMenu = wx.Menu()
copyitem = fileMenu.Append(wx.ID_COPY, "&Copy\tCtrl-C")
pasteitem = fileMenu.Append(wx.ID_PASTE, "&Paste\tCtrl-V")
fileMenu.AppendSeparator()
brkitem = fileMenu.Append(wx.ID_ANY, "&Break\tCtrl-B")
fileMenu.AppendSeparator()
quititem = fileMenu.Append(wx.ID_EXIT, "&Quit")
helpMenu = wx.Menu()
hotkeyitem = helpMenu.Append(wx.ID_ANY, "Program &Shortcuts")
menubar = wx.MenuBar()
menubar.Append(fileMenu, '&File')
menubar.Append(helpMenu, '&Help')
frame.SetMenuBar(menubar)
self._terminal = TerminalCtrl(panel)
self._terminal.SetSpacing(0)
self._terminal.SetWrap(True)
sizer.Add(self._terminal, 1, wx.EXPAND)
panelSizer.Add(panel, 1, wx.EXPAND)
panel.SetSizer(sizer)
frame.SetSizer(panelSizer)
frame.SetMinSize(wx.Size(313, 260))
frame.Show()
# Set up accelerators
accelC = wx.AcceleratorEntry(wx.ACCEL_CTRL, ord('C'), wx.ID_COPY)
accelV = wx.AcceleratorEntry(wx.ACCEL_CTRL, ord('V'), wx.ID_PASTE)
accelB = wx.AcceleratorEntry(wx.ACCEL_CTRL, ord('B'), brkitem.GetId())
accel = wx.AcceleratorTable([accelC, accelV, accelB])
frame.SetAcceleratorTable(accel)
# Bind on window events
frame.Bind(wx.EVT_CLOSE, self.onClose)
self._terminal.Bind(wx.EVT_CHAR, self.onChar)
# Bind Menu handlers
frame.Bind(wx.EVT_MENU, self.onClose, quititem)
frame.Bind(wx.EVT_MENU, self.showHotkeys, hotkeyitem)
frame.Bind(wx.EVT_MENU, lambda e: self.onCopy(), copyitem)
frame.Bind(wx.EVT_MENU, lambda e: self.onPaste(), pasteitem)
frame.Bind(wx.EVT_MENU, lambda e: self.send_break(), brkitem)
# Register for events from Serial Communications thread
EVT_SERIAL(frame, self.onSerialData)
# Ensure the terminal has focus
self._terminal.SetFocus()
self._wxObj = frame
self._tLock.release()
app.MainLoop()
def onChar(self, event):
code = event.GetUnicodeKey()
if code == wx.WXK_NONE:
code = event.GetKeyCode()
if (not 27 < code < 256) or event.HasAnyModifiers():
# So we don't consume the event
print('We don\'t process your kind here! (%d)' % code)
event.Skip()
return
print("CHAR: %s(%d)" % (chr(code), code))
In regards to the custom control, here is the definition.
import wx
from wx.lib.scrolledpanel import ScrolledPanel
class TerminalCtrl(ScrolledPanel, wx.Window):
pass # Removed implementation details
from EVT_CHAR never calls handler
No comments:
Post a Comment