import functools
import unittest
import tkinter
+from tkinter import TclError
import enum
from test import support
-from test.test_tkinter.support import AbstractTkTest, AbstractDefaultRootTest
+from test.test_tkinter.support import AbstractTkTest, AbstractDefaultRootTest, requires_tk
support.requires('gui')
for name in str(b).split('.'):
self.assertFalse(name.isidentifier(), msg=repr(name))
+ @requires_tk(8, 6, 6)
+ def test_tk_busy(self):
+ root = self.root
+ f = tkinter.Frame(root, name='myframe')
+ f2 = tkinter.Frame(root)
+ f.pack()
+ f2.pack()
+ b = tkinter.Button(f)
+ b.pack()
+ f.tk_busy_hold()
+ with self.assertRaisesRegex(TclError, 'unknown option "-spam"'):
+ f.tk_busy_configure(spam='eggs')
+ with self.assertRaisesRegex(TclError, 'unknown option "-spam"'):
+ f.tk_busy_cget('spam')
+ with self.assertRaisesRegex(TclError, 'unknown option "-spam"'):
+ f.tk_busy_configure('spam')
+ self.assertIsInstance(f.tk_busy_configure(), dict)
+
+ self.assertTrue(f.tk_busy_status())
+ self.assertFalse(root.tk_busy_status())
+ self.assertFalse(f2.tk_busy_status())
+ self.assertFalse(b.tk_busy_status())
+ self.assertIn(f, f.tk_busy_current())
+ self.assertIn(f, f.tk_busy_current('*.m?f*me'))
+ self.assertNotIn(f, f.tk_busy_current('*spam'))
+
+ f.tk_busy_forget()
+ self.assertFalse(f.tk_busy_status())
+ self.assertFalse(f.tk_busy_current())
+ with self.assertRaisesRegex(TclError, "can't find busy window"):
+ f.tk_busy_configure()
+ with self.assertRaisesRegex(TclError, "can't find busy window"):
+ f.tk_busy_forget()
+
+ @requires_tk(8, 6, 6)
+ def test_tk_busy_with_cursor(self):
+ root = self.root
+ if root._windowingsystem == 'aqua':
+ self.skipTest('the cursor option is not supported on OSX/Aqua')
+ f = tkinter.Frame(root, name='myframe')
+ f.pack()
+ f.tk_busy_hold(cursor='gumby')
+
+ self.assertEqual(f.tk_busy_cget('cursor'), 'gumby')
+ f.tk_busy_configure(cursor='heart')
+ self.assertEqual(f.tk_busy_cget('cursor'), 'heart')
+ self.assertEqual(f.tk_busy_configure()['cursor'][4], 'heart')
+ self.assertEqual(f.tk_busy_configure('cursor')[4], 'heart')
+
+ f.tk_busy_forget()
+ with self.assertRaisesRegex(TclError, "can't find busy window"):
+ f.tk_busy_cget('cursor')
+
def test_tk_setPalette(self):
root = self.root
root.tk_setPalette('black')
"""Ring a display's bell."""
self.tk.call(('bell',) + self._displayof(displayof))
+ def tk_busy_cget(self, option):
+ """Return the value of busy configuration option.
+
+ The widget must have been previously made busy by
+ tk_busy_hold(). Option may have any of the values accepted by
+ tk_busy_hold().
+ """
+ return self.tk.call('tk', 'busy', 'cget', self._w, '-'+option)
+ busy_cget = tk_busy_cget
+
+ def tk_busy_configure(self, cnf=None, **kw):
+ """Query or modify the busy configuration options.
+
+ The widget must have been previously made busy by
+ tk_busy_hold(). Options may have any of the values accepted by
+ tk_busy_hold().
+
+ Please note that the option database is referenced by the widget
+ name or class. For example, if a Frame widget with name "frame"
+ is to be made busy, the busy cursor can be specified for it by
+ either call:
+
+ w.option_add('*frame.busyCursor', 'gumby')
+ w.option_add('*Frame.BusyCursor', 'gumby')
+ """
+ if kw:
+ cnf = _cnfmerge((cnf, kw))
+ elif cnf:
+ cnf = _cnfmerge(cnf)
+ if cnf is None:
+ return self._getconfigure(
+ 'tk', 'busy', 'configure', self._w)
+ if isinstance(cnf, str):
+ return self._getconfigure1(
+ 'tk', 'busy', 'configure', self._w, '-'+cnf)
+ self.tk.call('tk', 'busy', 'configure', self._w, *self._options(cnf))
+ busy_config = busy_configure = tk_busy_config = tk_busy_configure
+
+ def tk_busy_current(self, pattern=None):
+ """Return a list of widgets that are currently busy.
+
+ If a pattern is given, only busy widgets whose path names match
+ a pattern are returned.
+ """
+ return [self._nametowidget(x) for x in
+ self.tk.splitlist(self.tk.call(
+ 'tk', 'busy', 'current', pattern))]
+ busy_current = tk_busy_current
+
+ def tk_busy_forget(self):
+ """Make this widget no longer busy.
+
+ User events will again be received by the widget.
+ """
+ self.tk.call('tk', 'busy', 'forget', self._w)
+ busy_forget = tk_busy_forget
+
+ def tk_busy_hold(self, **kw):
+ """Make this widget appear busy.
+
+ The specified widget and its descendants will be blocked from
+ user interactions. Normally update() should be called
+ immediately afterward to insure that the hold operation is in
+ effect before the application starts its processing.
+
+ The only supported configuration option is:
+
+ cursor: the cursor to be displayed when the widget is made
+ busy.
+ """
+ self.tk.call('tk', 'busy', 'hold', self._w, *self._options(kw))
+ busy = busy_hold = tk_busy = tk_busy_hold
+
+ def tk_busy_status(self):
+ """Return True if the widget is busy, False otherwise."""
+ return self.tk.getboolean(self.tk.call(
+ 'tk', 'busy', 'status', self._w))
+ busy_status = tk_busy_status
+
# Clipboard handling:
def clipboard_get(self, **kw):
"""Retrieve data from the clipboard on window's display.