Skip to content

gh-47655: Add support for user data of Tk virtual events to tkinter #7142

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it breaking change? Because f argument is moved one position to the right and number of arguments is changed. Just making a point in case you have missed it.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, d is no longer missing, comment lies.

# 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`.
Loading