• R/O
  • SSH

tkpane: Commit

Default repository for tkpane.py.


Commit MetaInfo

Revisãocbc0a1b31853d5b2ad4234df6adf53f15c5ce143 (tree)
Hora2018-03-04 03:46:18
AutorDreas Nielsen <dreas.nielsen@gmai...>
CommiterDreas Nielsen

Mensagem de Log

Modified alteration of background color when data are invalid to use the state settings of ttk widgets. Works as intended on Linux.

Mudança Sumário

Diff

diff -r bfbdd765fe25 -r cbc0a1b31853 doc/source/conf.py
--- a/doc/source/conf.py Fri Mar 02 08:18:47 2018 -0800
+++ b/doc/source/conf.py Sat Mar 03 10:46:18 2018 -0800
@@ -55,9 +55,9 @@
5555 # built documents.
5656 #
5757 # The short X.Y version.
58-version = u'0.23.0'
58+version = u'0.24.0'
5959 # The full version, including alpha/beta/rc tags.
60-release = u'0.23.0'
60+release = u'0.24.0'
6161
6262 # The language for content autogenerated by Sphinx. Refer to documentation
6363 # for a list of supported languages.
diff -r bfbdd765fe25 -r cbc0a1b31853 doc/source/index.rst
--- a/doc/source/index.rst Fri Mar 02 08:18:47 2018 -0800
+++ b/doc/source/index.rst Sat Mar 03 10:46:18 2018 -0800
@@ -281,7 +281,7 @@
281281
282282 1. Create any custom pane classes needed, or use those from ``tkpane.lib``.
283283 2. Create the layout of the application (or of an application window),
284- defining a Tkinter frame to hold each pane.
284+ defining a Tkinter frame or notebook page to hold each pane.
285285 3. Instantiate a pane object for each enclosing frame by passing the
286286 enclosing frame widget to the pane class's constructor method.
287287 4. If needed, use the ``requires()`` method to identify which frames
@@ -1169,8 +1169,8 @@
11691169 .. note::
11701170
11711171 The 'invalid' background color for themed (ttk) widgets is not
1172- getting properly set on Windows, where results may vary. This is
1173- evidently a defect in the ttk library itself.
1172+ getting set to light red on Windows when native widgets are being
1173+ used (as in the default theme).
11741174
11751175 2. Every pane that manages data must have a dictionary key (or keys)
11761176 to identify the data value(s). Every pane class in ``tkpane.lib``
diff -r bfbdd765fe25 -r cbc0a1b31853 setup.py
--- a/setup.py Fri Mar 02 08:18:47 2018 -0800
+++ b/setup.py Sat Mar 03 10:46:18 2018 -0800
@@ -2,7 +2,7 @@
22
33 setup(name='tkpane',
44 packages=['tkpane'],
5- version='0.23.0',
5+ version='0.24.0',
66 description="Encapsulates Tkinter UI elements in 'panes' that can be combined into an overall UI, integrating them by specifying callback functions and data keys.",
77 author='Dreas Nielsen',
88 author_email='dreas.nielsen@gmail.com',
diff -r bfbdd765fe25 -r cbc0a1b31853 test/test_invalid.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/test_invalid.py Sat Mar 03 10:46:18 2018 -0800
@@ -0,0 +1,119 @@
1+#!/usr/bin/python
2+# test_invalid.py
3+#
4+# PURPOSE
5+# Test the invalid state of several widgets by toggling their
6+# 'required' state on and off.
7+#
8+# NOTES
9+# 1.
10+#
11+# AUTHOR
12+# Dreas Nielsen
13+#
14+# HISTORY
15+# Date Remarks
16+# ---------- -----------------------------------------------------------
17+# 2018-03-03 Created. RDN.
18+# =========================================================================
19+
20+try:
21+ import Tkinter as tk
22+except:
23+ import tkinter as tk
24+
25+import tkpane
26+import tkpane.lib
27+import tklayout
28+
29+
30+
31+list1 = ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"]
32+
33+
34+
35+lo = tklayout.AppLayout()
36+buttons = lo.row_elements(["empty_pane", "button1", "button2"], column_weights=[1,0,0])
37+col1 = lo.column_elements(["entry", "entry2", "combobox", "listbox"])
38+col2 = lo.column_elements(["spin", "scale", "checkbox", "text"])
39+row1 = lo.row_elements([col1, col2])
40+app = lo.column_elements([row1, buttons])
41+
42+root = tk.Tk()
43+root.title("Testing of Enable/Disable")
44+
45+appframe = tk.Frame(root, padx=9, pady=9)
46+appframe.pack(expand=True, fill=tk.BOTH)
47+
48+lo.create_layout(appframe, app)
49+
50+panes = tkpane.build_ui(lo, appframe, app, {
51+ "entry": lambda p: tkpane.lib.EntryPane(p, "entry1", "ttk.Entry:", "entry1"),
52+ "entry2": lambda p: tkpane.lib.EntryPane(p, "entry2", "Disabled:", "entry2"),
53+ "combobox": lambda p: tkpane.lib.ComboboxPane(p, "combo", "Pick one:", list1, item_only=True),
54+ "listbox": lambda p: tkpane.lib.ListboxPane(p, "listbox1", items=list1, rows=5),
55+ "scale": lambda p: tkpane.lib.ScalePane(p, "scale1", tk.HORIZONTAL, 80, 0, 255, 128, "scale1"),
56+ "spin": lambda p: tkpane.lib.SpinboxPane(p, "spin1", "Spin", 0 , 13, "spin1"),
57+ "checkbox": lambda p: tkpane.lib.CheckboxPane(p, "checkbox", "Check?"),
58+ "text": lambda p: tkpane.lib.TextPane(p, optiondict={"height": 8, "width": 20}),
59+ "button1": lambda p: tkpane.lib.ButtonPane(p, "Required"),
60+ "button2": lambda p: tkpane.lib.ButtonPane(p, "Not required")
61+ })
62+
63+# Get references to the actual pane objects.
64+entry = panes["entry"]
65+entry2 = panes["entry2"]
66+combobox = panes["combobox"]
67+listbox = panes["listbox"]
68+scale = panes["scale"]
69+spin = panes["spin"]
70+checkbox = panes["checkbox"]
71+text = panes["text"]
72+button1 = panes["button1"]
73+button2 = panes["button2"]
74+
75+entry2.keys_to_enable = ["No such key will ever be generated."]
76+tkpane.enable_or_disable_all([entry2])
77+
78+# Make button1 set all controls to required
79+def b1_click(*args):
80+ entry.required = True
81+ entry2.required = True
82+ listbox.required = True
83+ scale.required = True
84+ spin.required = True
85+ checkbox.required = True
86+ text.required = True
87+ entry.handle_change_validity(False)
88+ entry2.handle_change_validity(False)
89+ combobox.handle_change_validity(False)
90+ listbox.handle_change_validity(False)
91+ scale.handle_change_validity(False)
92+ spin.handle_change_validity(False)
93+ checkbox.handle_change_validity(False)
94+ text.handle_change_validity(False)
95+button1.set_button_action(b1_click)
96+
97+# Button2 makes all controls not required.
98+def b2_click(*args):
99+ entry.required = False
100+ entry2.required = False
101+ listbox.required = False
102+ scale.required = False
103+ spin.required = False
104+ checkbox.required = False
105+ text.required = False
106+ entry.handle_change_validity(True)
107+ entry2.handle_change_validity(True)
108+ combobox.handle_change_validity(True)
109+ listbox.handle_change_validity(True)
110+ scale.handle_change_validity(True)
111+ spin.handle_change_validity(True)
112+ checkbox.handle_change_validity(True)
113+ text.handle_change_validity(True)
114+button2.set_button_action(b2_click)
115+
116+
117+
118+# Run the application
119+root.mainloop()
diff -r bfbdd765fe25 -r cbc0a1b31853 tkpane/tkpane.py
--- a/tkpane/tkpane.py Fri Mar 02 08:18:47 2018 -0800
+++ b/tkpane/tkpane.py Sat Mar 03 10:46:18 2018 -0800
@@ -27,7 +27,7 @@
2727 that pass specific data to allow communication between panes, and callback methods
2828 for reporting status and progress."""
2929
30-__version__ = "0.23.0"
30+__version__ = "0.24.0"
3131
3232
3333 try:
@@ -193,7 +193,7 @@
193193 # directly, it will not be applied immediately; use 'set_invalid_color()'
194194 # to assign *and* apply it.
195195 self.invalid_color = "#fff5ff"
196- self.invalid_disabled_color = "#f6f0f6"
196+ self.invalid_disabled_color = "#ece7ec"
197197 self.valid_color = "#ffffff"
198198 #=======================================================================
199199 # ASSIGNABLE CALLBACKS
@@ -293,7 +293,13 @@
293293 return True
294294
295295 def show_widget_validity(self, widget, is_valid):
296- """Set the widget's background color to the 'valid' or 'invalid' color."""
296+ """Set the widget's background color to the 'valid' or 'invalid' color.
297+
298+ tk and ttk widgets are handled differently. This implementation assumes
299+ that Text, Listbox, and Spinbox widgets are all tk widgets, and all others
300+ are ttk widgets (as in tkpane.lib). If other types of widgets
301+ are used (e.g., a tk.Entry widget), this method will have to be overridden.
302+ """
297303 if self.invalid_color is not None:
298304 wclass = widget.winfo_class()
299305 if wclass in ("Text", "Listbox", "Spinbox"):
@@ -307,18 +313,19 @@
307313 # ttk widgets.
308314 try:
309315 sname = widget["style"] or wclass
310- if sname.startswith("TkPaneInvalid."):
311- if is_valid:
312- nname = sname[14:]
313- widget['style'] = nname
314- else:
315- if not is_valid:
316- invname = "TkPaneInvalid." + sname
317- # The following does not work on Linux on Windows.
318- #ttk.Style().configure(invname, background=[('disabled',self.invalid_disabled_color), ('active',self.invalid_color)])
319- # The following works on Linux. On Windows, results vary, but may include no effect.
320- ttk.Style().configure(invname, fieldbackground=self.invalid_color)
321- widget['style'] = invname
316+ disabled_color = ttk.Style().lookup(sname, 'fieldbackground', ('disabled',))
317+ ttk.Style().map(sname,
318+ fieldbackground=[(['invalid','!disabled'], self.invalid_color),
319+ (['invalid','disabled'], self.invalid_disabled_color),
320+ (['!invalid', 'disabled'], disabled_color)])
321+ vstate = '!invalid' if is_valid else 'invalid'
322+ st = list(widget.state())
323+ if 'invalid' in st:
324+ st.remove('invalid')
325+ if '!invalid' in st:
326+ st.remove('!invalid')
327+ st.append(vstate)
328+ widget.state(st)
322329 except:
323330 pass
324331
Show on old repository browser