mirror of
https://github.com/python/cpython
synced 2024-10-07 05:24:55 +00:00
gh-72684: Tkinter: provide interface for "tk busy" subcommands (GH-107684)
Add tkinter.Misc methods: tk_busy_hold(), tk_busy_configure(), tk_busy_cget(), tk_busy_forget(), tk_busy_current(), and tk_busy_status().
This commit is contained in:
parent
ca0c6c1f1e
commit
79db9d9a0e
|
@ -144,6 +144,15 @@ pathlib
|
||||||
:meth:`~pathlib.Path.is_dir`.
|
:meth:`~pathlib.Path.is_dir`.
|
||||||
(Contributed by Barney Gale in :gh:`77609` and :gh:`105793`.)
|
(Contributed by Barney Gale in :gh:`77609` and :gh:`105793`.)
|
||||||
|
|
||||||
|
tkinter
|
||||||
|
-------
|
||||||
|
|
||||||
|
* Add :mod:`tkinter` widget methods:
|
||||||
|
:meth:`!tk_busy_hold`, :meth:`!tk_busy_configure`,
|
||||||
|
:meth:`!tk_busy_cget`, :meth:`!tk_busy_forget`,
|
||||||
|
:meth:`!tk_busy_current`, and :meth:`!tk_busy_status`.
|
||||||
|
(Contributed by Miguel, klappnase and Serhiy Storchaka in :gh:`72684`.)
|
||||||
|
|
||||||
traceback
|
traceback
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import functools
|
import functools
|
||||||
import unittest
|
import unittest
|
||||||
import tkinter
|
import tkinter
|
||||||
|
from tkinter import TclError
|
||||||
import enum
|
import enum
|
||||||
from test import support
|
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')
|
support.requires('gui')
|
||||||
|
|
||||||
|
@ -36,6 +37,59 @@ def test_generated_names(self):
|
||||||
for name in str(b).split('.'):
|
for name in str(b).split('.'):
|
||||||
self.assertFalse(name.isidentifier(), msg=repr(name))
|
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):
|
def test_tk_setPalette(self):
|
||||||
root = self.root
|
root = self.root
|
||||||
root.tk_setPalette('black')
|
root.tk_setPalette('black')
|
||||||
|
|
|
@ -901,6 +901,85 @@ def bell(self, displayof=0):
|
||||||
"""Ring a display's bell."""
|
"""Ring a display's bell."""
|
||||||
self.tk.call(('bell',) + self._displayof(displayof))
|
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:
|
# Clipboard handling:
|
||||||
def clipboard_get(self, **kw):
|
def clipboard_get(self, **kw):
|
||||||
"""Retrieve data from the clipboard on window's display.
|
"""Retrieve data from the clipboard on window's display.
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
Add :mod:`tkinter` widget methods: :meth:`!tk_busy_hold`,
|
||||||
|
:meth:`!tk_busy_configure`, :meth:`!tk_busy_cget`, :meth:`!tk_busy_forget`,
|
||||||
|
:meth:`!tk_busy_current`, and :meth:`!tk_busy_status`.
|
Loading…
Reference in a new issue