Skip to content

Commit 57b50ec

Browse files
authored
Merge pull request #19 from davidhozic/develop
Develop
2 parents 02efaa3 + dfb4419 commit 57b50ec

35 files changed

+477
-37
lines changed

.readthedocs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ build:
1212
apt_packages:
1313
- inkscape
1414
tools:
15-
python: "3.8"
15+
python: "3.9"
1616
jobs:
1717
pre_build:
1818
- pip install .[docs]

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Installation
1717
----------------------
1818
TkClassWizard can be installed though command prompt/terminal using the bottom commands.
1919

20-
Pre-requirement: `Python (minimum v3.8) <https://www.python.org/downloads/>`_
20+
Pre-requirement: `Python (minimum v3.9) <https://www.python.org/downloads/>`_
2121

2222

2323
.. code-block:: bash

docs/source/changelog.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@ Glossary
2424
Releases
2525
---------------------
2626

27+
v1.2.0
28+
================
29+
- Added the ability of nicknaming structured objects.
30+
- Generic types support (Parametric types)
31+
- :ref:`Type aliasing`
32+
- Object nicknaming
33+
- Tooltip when hovering over fields, which shows the full value.
34+
- |BREAK_CH| Minimal Python version bumped to Python 3.9
35+
2736

2837
v1.1.1
2938
================

docs/source/conf.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@
2929

3030

3131
# -- General configuration ---------------------------------------------------
32-
root_doc = 'index'
33-
3432
numfig = True
3533

3634
# Add any Sphinx extension module names here, as strings. They can be
@@ -80,7 +78,7 @@
8078

8179
# Intersphinx
8280
intersphinx_mapping = {
83-
"Python" : ("https://docs.python.org/3/", None)
81+
"python" : ("https://docs.python.org/3/", None)
8482
}
8583

8684
# ----------- HTML ----------- #

docs/source/guide/aliasing.rst

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
========================
2+
Type aliasing
3+
========================
4+
5+
TkClassWizard allows types to be aliased.
6+
Alias is an alternative name or nickname for a specific type.
7+
8+
Type aliasing can be done within the :func:`tkclasswiz.aliasing.register_alias` function.
9+
An alias can be obtained through :func:`tkclasswiz.aliasing.get_aliased_name` function.
10+
11+
For example, we can give the :class:`~datetime.timedelta` type an alternative name:
12+
13+
.. code-block:: python
14+
15+
from datetime import timedelta
16+
import tkclasswiz as wiz
17+
18+
wiz.register_alias(timedelta, "Duration")
19+
20+
21+
If we define a type alias like in the above example, then the timedelta class will look like shown in the following 2 images:
22+
23+
24+
.. figure:: ./images/type_alias_one_frame_param.png
25+
:width: 15cm
26+
27+
:class:`~datetime.timedelta` type alias display after definition of parameters.
28+
29+
|
30+
31+
.. figure:: ./images/new_define_frame_struct_alias_new_timedelta.png
32+
:width: 15cm
33+
34+
:class:`~datetime.timedelta` type alias display inside the New object menu.

docs/source/guide/defining.rst

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ This is how our example from the previous page looks inside a GUI:
99
:width: 15cm
1010

1111

12-
1312
Defining structured data (objects)
1413
=======================================
1514

@@ -45,7 +44,22 @@ load them from a JSON file back into the GUI.
4544
For verification purposes, the JSON file contains the full path to the defining class.
4645
Changing the class path requires users to update the corresponding path within the JSON files as well.
4746

48-
Going down further we can see multiple rows, each one of the corresponding to a parameter.
47+
Below the "Template" button, an entry labeled "Object nickname" is located.
48+
This entry can be used to give an object a nickname.
49+
The nickname will be displayed before the class's name,
50+
allowing the object to be easily recognized at a glance.
51+
52+
.. image:: ./images/new_define_frame_struct_nickname.png
53+
:width: 15cm
54+
55+
This is how the object will look inside a Combobox, if it is given the name "David's car"
56+
(notice the parentheses at the beginning):
57+
58+
.. image:: ./images/example_gui_view_defined_nickname_car.png
59+
:width: 15cm
60+
61+
62+
Going down further we can see multiple rows, each one of them corresponding to a parameter.
4963

5064
.. image:: ./images/new_define_frame_struct_parameters.png
5165
:width: 15cm
@@ -56,7 +70,32 @@ The next item on the right is a Combobox (:class:`~tkclasswiz.storage.ComboBoxOb
5670
which is a dropdown menu used for storing the value of each defined parameter.
5771
This dropdown menu can contain multiple values while we are still editing,
5872
which we can access through the down arrow-like symbol located on the rightmost side of the Combobox.
59-
When the definition frame is closed all the other values that were not selected inside the Combobox get discarded.
73+
When the definition frame is closed, all the other (not selected) values get discarded.
74+
75+
76+
.. note::
77+
78+
While the dropdown menu (Combobox) can contains values manually defined through the GUI,
79+
it will sometimes have some predefined values. These values can be:
80+
81+
- None: Parameter was annotated with :class:`typing.Optional` (``Optional[<type>]``) or
82+
with :class:`typing.Union` (``Union[None, ...]``)
83+
- ``True`` and ``False``: Parameter is a boolean parameter
84+
- Literal string values: Parameter is a literal string, meaning it is annotated with
85+
:class:`typing.Literal`. E. g, ``Literal['value1', 'value2', ...]`` annotation will produce the values 'value1' and
86+
'value2' inside the Combobox.
87+
88+
89+
.. code-block:: python
90+
91+
class Person:
92+
def __init__(self, name: str, job_type: Literal["Science", "Technology", "Engineering", "Math"]):
93+
...
94+
95+
.. image:: ./images/new_define_frame_struct_literal_values.png
96+
:width: 15cm
97+
98+
6099
The dropdown menu is followed by 3 buttons:
61100

62101
- "New": is a dropdown menu button, which allows to define multiple data types that the parameter accepts. It can

docs/source/guide/generics.rst

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
=========================
2+
Generic types (classes)
3+
=========================
4+
5+
A generic type in Python is a class, that inherits the :class:`typing.Generic` class.
6+
It can be used to define arbitrary type parameters, which can be given a value using a subscription operator ``[]``.
7+
8+
Arbitrary types / type variables can be created using the :class:`typing.TypeVar` class.
9+
10+
.. note::
11+
12+
Since Python 3.12, the :class:`typing.TypeVar` no longer requires manual definition
13+
and can be omitted.
14+
15+
16+
.. code-block:: python
17+
:linenos:
18+
19+
from typing import Generic, TypeVar
20+
21+
22+
T = TypeVar('T') # From Python 3.12 forward this is optional
23+
24+
class MyClass(Generic[T]):
25+
def __init__(self, a: int, b: T):
26+
...
27+
28+
29+
my_instance1: MyClass[float] = MyClass(5, 5.5)
30+
my_instance2: MyClass[str] = MyClass(5, "Some text")
31+
my_instance3: MyClass[int] = MyClass(5, 0)
32+
33+
34+
In the above example, the ``T`` is a type variable. It is also a type parameter inside ``MyClass``.
35+
When instances are created, the variables are annotated with a type subscription (e. g., ``MyClass[int]``).
36+
37+
While Python itself doesn't care about the types given in the subscription, and just ignores incorrect types,
38+
TkClassWizard resolves these subscripted types into the ``__init__`` function of a class, allowing the definition
39+
of arbitrary types with the use of type generics.
40+
41+
If we take the above example and pop it into TkClassWizard with ``MyClass`` having a :class:`float` annotation,
42+
we would get the following types in the ``New <type>`` options:
43+
44+
.. image:: ./images/new_define_frame_struct_generics.png
45+
:width: 15cm
46+
47+
48+
.. code-block:: python
49+
:caption: Generic type, given :class:`float` as type parameter
50+
:linenos:
51+
:emphasize-lines: 21
52+
53+
from typing import Generic, TypeVar
54+
55+
import tkclasswiz as wiz
56+
import tkinter as tk
57+
import tkinter.ttk as ttk
58+
59+
T = TypeVar('T') # From Python 3.12 forward this is optional
60+
61+
class MyClass(Generic[T]):
62+
def __init__(self, a: int, b: T):
63+
...
64+
65+
root = tk.Tk("Test")
66+
67+
combo = wiz.ComboBoxObjects(root)
68+
combo.pack(fill=tk.X, padx=5)
69+
70+
def open():
71+
window = wiz.ObjectEditWindow() # The object definition window / wizard
72+
window.open_object_edit_frame(
73+
MyClass[float],
74+
combo
75+
) # Open the actual frame
76+
77+
ttk.Button(text="Define", command=open).pack()
78+
root.mainloop()
Loading
Loading
Loading

0 commit comments

Comments
 (0)