Skip to content
15 changes: 12 additions & 3 deletions Lib/tkinter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,10 @@ class Event:
type - type of the event as a number
widget - widget in which the event occurred
delta - delta of wheel movement (MouseWheel)
detail - certain fixed strings (see tcl/tk documentation)
(Enter, Leave, FocusIn, FocusOut, ConfigureRequest)
user_data - data string which was passed to event_generate or empty string
(VirtualEvent)
"""

def __repr__(self):
Expand Down Expand Up @@ -1711,7 +1715,7 @@ def _root(self):
w = self
while w.master is not None: w = w.master
return w
_subst_format = ('%#', '%b', '%f', '%h', '%k',
_subst_format = ('%#', '%b', '%d', '%f', '%h', '%k',
'%s', '%t', '%w', '%x', '%y',
'%A', '%E', '%K', '%N', '%W', '%T', '%X', '%Y', '%D')
_subst_format_str = " ".join(_subst_format)
Expand All @@ -1732,11 +1736,14 @@ def getint_event(s):
if any(isinstance(s, tuple) for s in args):
args = [s[0] if isinstance(s, tuple) and len(s) == 1 else s
for s in args]
nsign, b, f, h, k, s, t, w, x, y, A, E, K, N, W, T, X, Y, D = args
# Missing: (a, c, d, m, o, v, B, R)
nsign, b, d, f, h, k, s, t, w, x, y, A, E, K, N, W, T, X, Y, D = args
Comment thread
serhiy-storchaka marked this conversation as resolved.
# Missing: (a, c, m, o, v, B, R)
e = Event()
# serial field: valid for all events
# number of button: ButtonPress and ButtonRelease events only
# detail: for Enter, Leave, FocusIn, FocusOut and ConfigureRequest
# events certain fixed strings (see tcl/tk documentation)
# user_data: data string from a virtual event or an empty string
# height field: Configure, ConfigureRequest, Create,
# ResizeRequest, and Expose events only
# keycode field: KeyPress and KeyRelease events only
Expand All @@ -1750,6 +1757,8 @@ def getint_event(s):
# KeyRelease, and Motion events
e.serial = getint(nsign)
e.num = getint_event(b)
e.user_data = d
e.detail = d
try: e.focus = getboolean(f)
except TclError: pass
e.height = getint_event(h)
Expand Down
49 changes: 49 additions & 0 deletions Lib/tkinter/test/test_tkinter/test_event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import unittest
import tkinter
import _tkinter
from test.support import requires, run_unittest
from tkinter.test.support import AbstractTkTest

requires('gui')

class EventTest(AbstractTkTest, unittest.TestCase):

called = False
test_data = None

# pump_events function 'borrowed' from ivan_pozdeev on stackoverflow
def pump_events(self):
while self.root.dooneevent(_tkinter.ALL_EVENTS | _tkinter.DONT_WAIT):
pass

def test_virtual_event(self):
def receive(e):
EventTest.called = True
self.assertIsInstance(e, tkinter.Event)
self.assertEqual(e.type, tkinter.EventType.VirtualEvent)
self.assertIsInstance(e.user_data, str)
if EventTest.test_data is not None:
self.assertEqual(e.user_data, EventTest.test_data)
else:
self.assertEqual(e.user_data, '')
self.pump_events()
EventTest.called = False
b = self.root.bind('<<TEST>>', lambda e:receive(e))
self.root.event_generate('<<TEST>>')
self.pump_events()
self.assertTrue(EventTest.called)
EventTest.called = False
EventTest.test_data = 'test'
self.root.event_generate('<<TEST>>', data='test')
self.pump_events()
self.assertTrue(EventTest.called)
self.root.unbind('<<TEST>>', b)
EventTest.called = False
self.root.event_generate('<<TEST>>')
self.pump_events()
self.assertFalse(EventTest.called)

tests_gui = (EventTest, )

if __name__ == "__main__":
run_unittest(*tests_gui)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add support for user data of Tk virtual events to :mod:`tkinter`.