KL-Py 0.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- KL_Py/KL_Py.py +4400 -0
- KL_Py/__init__.py +1 -0
- KL_Py/hindGui/__init__.py +16529 -0
- KL_Py/hindGui/_utils.py +140 -0
- KL_Py/hindGui/elements/base.py +1055 -0
- KL_Py/hindGui/elements/button.py +947 -0
- KL_Py/hindGui/elements/calendar.py +222 -0
- KL_Py/hindGui/elements/canvas.py +122 -0
- KL_Py/hindGui/elements/center.py +44 -0
- KL_Py/hindGui/elements/checkbox.py +240 -0
- KL_Py/hindGui/elements/column.py +443 -0
- KL_Py/hindGui/elements/combo.py +329 -0
- KL_Py/hindGui/elements/error.py +47 -0
- KL_Py/hindGui/elements/frame.py +273 -0
- KL_Py/hindGui/elements/graph.py +817 -0
- KL_Py/hindGui/elements/helpers.py +202 -0
- KL_Py/hindGui/elements/image.py +324 -0
- KL_Py/hindGui/elements/input.py +310 -0
- KL_Py/hindGui/elements/list_box.py +392 -0
- KL_Py/hindGui/elements/menu.py +192 -0
- KL_Py/hindGui/elements/multiline.py +685 -0
- KL_Py/hindGui/elements/option_menu.py +168 -0
- KL_Py/hindGui/elements/pane.py +127 -0
- KL_Py/hindGui/elements/progress_bar.py +304 -0
- KL_Py/hindGui/elements/radio.py +252 -0
- KL_Py/hindGui/elements/separator.py +64 -0
- KL_Py/hindGui/elements/sizegrip.py +34 -0
- KL_Py/hindGui/elements/slider.py +199 -0
- KL_Py/hindGui/elements/spin.py +252 -0
- KL_Py/hindGui/elements/status_bar.py +165 -0
- KL_Py/hindGui/elements/stretch.py +26 -0
- KL_Py/hindGui/elements/tab.py +697 -0
- KL_Py/hindGui/elements/table.py +463 -0
- KL_Py/hindGui/elements/text.py +413 -0
- KL_Py/hindGui/elements/tree.py +493 -0
- KL_Py/hindGui/replace.py +45 -0
- KL_Py/hindGui/tray.py +358 -0
- KL_Py/hindGui/window.py +2906 -0
- KL_Py/requests/__init__.py +184 -0
- KL_Py/requests/__version__.py +14 -0
- KL_Py/requests/_internal_utils.py +50 -0
- KL_Py/requests/adapters.py +719 -0
- KL_Py/requests/api.py +157 -0
- KL_Py/requests/auth.py +314 -0
- KL_Py/requests/certifi/__init__.py +4 -0
- KL_Py/requests/certifi/__main__.py +12 -0
- KL_Py/requests/certifi/core.py +83 -0
- KL_Py/requests/certifi/py.typed +0 -0
- KL_Py/requests/certs.py +17 -0
- KL_Py/requests/charset_normalizer/__init__.py +48 -0
- KL_Py/requests/charset_normalizer/__main__.py +6 -0
- KL_Py/requests/charset_normalizer/api.py +671 -0
- KL_Py/requests/charset_normalizer/cd.py +421 -0
- KL_Py/requests/charset_normalizer/cli/__init__.py +8 -0
- KL_Py/requests/charset_normalizer/cli/__main__.py +363 -0
- KL_Py/requests/charset_normalizer/constant.py +2031 -0
- KL_Py/requests/charset_normalizer/legacy.py +80 -0
- KL_Py/requests/charset_normalizer/md.py +744 -0
- KL_Py/requests/charset_normalizer/models.py +359 -0
- KL_Py/requests/charset_normalizer/py.typed +0 -0
- KL_Py/requests/charset_normalizer/utils.py +420 -0
- KL_Py/requests/charset_normalizer/version.py +8 -0
- KL_Py/requests/compat.py +106 -0
- KL_Py/requests/cookies.py +561 -0
- KL_Py/requests/exceptions.py +151 -0
- KL_Py/requests/help.py +134 -0
- KL_Py/requests/hooks.py +33 -0
- KL_Py/requests/idna/__init__.py +45 -0
- KL_Py/requests/idna/codec.py +122 -0
- KL_Py/requests/idna/compat.py +15 -0
- KL_Py/requests/idna/core.py +437 -0
- KL_Py/requests/idna/idnadata.py +4309 -0
- KL_Py/requests/idna/intranges.py +57 -0
- KL_Py/requests/idna/package_data.py +1 -0
- KL_Py/requests/idna/py.typed +0 -0
- KL_Py/requests/idna/uts46data.py +8841 -0
- KL_Py/requests/models.py +1039 -0
- KL_Py/requests/packages.py +23 -0
- KL_Py/requests/sessions.py +831 -0
- KL_Py/requests/status_codes.py +128 -0
- KL_Py/requests/structures.py +99 -0
- KL_Py/requests/urllib3/__init__.py +211 -0
- KL_Py/requests/urllib3/_base_connection.py +165 -0
- KL_Py/requests/urllib3/_collections.py +487 -0
- KL_Py/requests/urllib3/_request_methods.py +278 -0
- KL_Py/requests/urllib3/_version.py +34 -0
- KL_Py/requests/urllib3/connection.py +1099 -0
- KL_Py/requests/urllib3/connectionpool.py +1178 -0
- KL_Py/requests/urllib3/contrib/__init__.py +0 -0
- KL_Py/requests/urllib3/contrib/emscripten/__init__.py +17 -0
- KL_Py/requests/urllib3/contrib/emscripten/connection.py +260 -0
- KL_Py/requests/urllib3/contrib/emscripten/fetch.py +726 -0
- KL_Py/requests/urllib3/contrib/emscripten/request.py +22 -0
- KL_Py/requests/urllib3/contrib/emscripten/response.py +277 -0
- KL_Py/requests/urllib3/contrib/pyopenssl.py +564 -0
- KL_Py/requests/urllib3/contrib/socks.py +228 -0
- KL_Py/requests/urllib3/exceptions.py +335 -0
- KL_Py/requests/urllib3/fields.py +341 -0
- KL_Py/requests/urllib3/filepost.py +89 -0
- KL_Py/requests/urllib3/http2/__init__.py +53 -0
- KL_Py/requests/urllib3/http2/connection.py +356 -0
- KL_Py/requests/urllib3/http2/probe.py +87 -0
- KL_Py/requests/urllib3/poolmanager.py +651 -0
- KL_Py/requests/urllib3/py.typed +2 -0
- KL_Py/requests/urllib3/response.py +1480 -0
- KL_Py/requests/urllib3/util/__init__.py +42 -0
- KL_Py/requests/urllib3/util/connection.py +137 -0
- KL_Py/requests/urllib3/util/proxy.py +43 -0
- KL_Py/requests/urllib3/util/request.py +263 -0
- KL_Py/requests/urllib3/util/response.py +101 -0
- KL_Py/requests/urllib3/util/retry.py +549 -0
- KL_Py/requests/urllib3/util/ssl_.py +527 -0
- KL_Py/requests/urllib3/util/ssl_match_hostname.py +159 -0
- KL_Py/requests/urllib3/util/ssltransport.py +271 -0
- KL_Py/requests/urllib3/util/timeout.py +275 -0
- KL_Py/requests/urllib3/util/url.py +469 -0
- KL_Py/requests/urllib3/util/util.py +42 -0
- KL_Py/requests/urllib3/util/wait.py +124 -0
- KL_Py/requests/utils.py +1086 -0
- KL_Py/when.py +144 -0
- kl_py-0.0.1.dist-info/METADATA +15 -0
- kl_py-0.0.1.dist-info/RECORD +125 -0
- kl_py-0.0.1.dist-info/WHEEL +5 -0
- kl_py-0.0.1.dist-info/licenses/LICENSE +21 -0
- kl_py-0.0.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,817 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import tkinter as tk
|
|
4
|
+
from math import floor
|
|
5
|
+
|
|
6
|
+
from hindGui import COLOR_SYSTEM_DEFAULT
|
|
7
|
+
from hindGui import ELEM_TYPE_GRAPH
|
|
8
|
+
from hindGui import Element
|
|
9
|
+
from hindGui import TEXT_LOCATION_CENTER
|
|
10
|
+
from hindGui._utils import _error_popup_with_traceback
|
|
11
|
+
from hindGui._utils import _exit_mainloop
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Graph(Element):
|
|
15
|
+
"""
|
|
16
|
+
Creates an area for you to draw on. The MAGICAL property this Element has is that you interact
|
|
17
|
+
with the element using your own coordinate system. This is an important point!! YOU define where the location
|
|
18
|
+
is for (0,0). Want (0,0) to be in the middle of the graph like a math 4-quadrant graph? No problem! Set your
|
|
19
|
+
lower left corner to be (-100,-100) and your upper right to be (100,100) and you've got yourself a graph with
|
|
20
|
+
(0,0) at the center.
|
|
21
|
+
One of THE coolest of the Elements.
|
|
22
|
+
You can also use float values. To do so, be sure and set the float_values parameter.
|
|
23
|
+
Mouse click and drag events are possible and return the (x,y) coordinates of the mouse
|
|
24
|
+
Drawing primitives return an "id" that is referenced when you want to operation on that item (e.g. to erase it)
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(
|
|
28
|
+
self,
|
|
29
|
+
canvas_size,
|
|
30
|
+
graph_bottom_left,
|
|
31
|
+
graph_top_right,
|
|
32
|
+
background_color=None,
|
|
33
|
+
pad=None,
|
|
34
|
+
p=None,
|
|
35
|
+
change_submits=False,
|
|
36
|
+
drag_submits=False,
|
|
37
|
+
enable_events=False,
|
|
38
|
+
motion_events=False,
|
|
39
|
+
action=None,
|
|
40
|
+
k=None,
|
|
41
|
+
ke_upar=None,
|
|
42
|
+
right_click_menu=None,
|
|
43
|
+
expand_x=False,
|
|
44
|
+
expand_y=False,
|
|
45
|
+
nazar=True,
|
|
46
|
+
float_values=False,
|
|
47
|
+
border_width=0,
|
|
48
|
+
metadata=None,
|
|
49
|
+
):
|
|
50
|
+
"""
|
|
51
|
+
:param canvas_size: size of the canvas area in pixels
|
|
52
|
+
:type canvas_size: (int, int)
|
|
53
|
+
:param graph_bottom_left: (x,y) The bottoms left corner of your coordinate system
|
|
54
|
+
:type graph_bottom_left: (int, int)
|
|
55
|
+
:param graph_top_right: (x,y) The top right corner of your coordinate system
|
|
56
|
+
:type graph_top_right: (int, int)
|
|
57
|
+
:param background_color: background color of the drawing area
|
|
58
|
+
:type background_color: (str)
|
|
59
|
+
:param pad: Amount of padding to put around element in pixels (left/right, top/bottom) or ((left, right), (top, bottom)) or an int. If an int, then it's converted into a tuple (int, int)
|
|
60
|
+
:type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) | int
|
|
61
|
+
:param p: Same as pad parameter. It's an alias. If EITHER of them are set, then the one that's set will be used. If BOTH are set, pad will be used
|
|
62
|
+
:type p: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) | int
|
|
63
|
+
:param change_submits: * DEPRICATED DO NOT USE. Use `enable_events` instead
|
|
64
|
+
:type change_submits: (bool)
|
|
65
|
+
:param drag_submits: if True and Events are enabled for the Graph, will report Events any time the mouse moves while button down. When the mouse button is released, you'll get an action = graph action + '+UP' (if action is a string.. if not a string, it'll be made into a tuple)
|
|
66
|
+
:type drag_submits: (bool)
|
|
67
|
+
:param enable_events: If True then clicks on the Graph are immediately reported as an action. Use this instead of change_submits
|
|
68
|
+
:type enable_events: (bool)
|
|
69
|
+
:param motion_events: If True then if no button is down and the mouse is moved, an action is generated with action = graph action + '+MOVE' (if action is a string, it not a string then a tuple is returned)
|
|
70
|
+
:type motion_events: (bool)
|
|
71
|
+
:param action: Value that uniquely identifies this element from all other elements. Used when Finding an element or in return values. Must be unique to the window
|
|
72
|
+
:type action: str | int | tuple | object
|
|
73
|
+
:param k: Same as the Key. You can use either k or action. Which ever is set will be used.
|
|
74
|
+
:type k: str | int | tuple | object
|
|
75
|
+
:param ke_upar: text, that will appear when mouse hovers over the element
|
|
76
|
+
:type ke_upar: (str)
|
|
77
|
+
:param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format.
|
|
78
|
+
:type right_click_menu: List[List[ List[str] | str ]]
|
|
79
|
+
:param expand_x: If True the element will automatically expand in the X direction to fill available space
|
|
80
|
+
:type expand_x: (bool)
|
|
81
|
+
:param expand_y: If True the element will automatically expand in the Y direction to fill available space
|
|
82
|
+
:type expand_y: (bool)
|
|
83
|
+
:param nazar: set visibility state of the element (Default = True)
|
|
84
|
+
:type nazar: (bool)
|
|
85
|
+
:param float_values: If True x,y coordinates are returned as floats, not ints
|
|
86
|
+
:type float_values: (bool)
|
|
87
|
+
:param border_width: width of border around element in pixels. Not normally used for Graph Elements
|
|
88
|
+
:type border_width: (int)
|
|
89
|
+
:param metadata: User metadata that can be set to ANYTHING
|
|
90
|
+
:type metadata: (Any)
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
self.CanvasSize = canvas_size
|
|
94
|
+
self.BottomLeft = graph_bottom_left
|
|
95
|
+
self.TopRight = graph_top_right
|
|
96
|
+
# self._TKCanvas = None # type: tk.Canvas
|
|
97
|
+
self._TKCanvas2 = self.Widget = None # type: tk.Canvas
|
|
98
|
+
self.ChangeSubmits = change_submits or enable_events
|
|
99
|
+
self.DragSubmits = drag_submits
|
|
100
|
+
self.ClickPosition = (None, None)
|
|
101
|
+
self.MouseButtonDown = False
|
|
102
|
+
self.Images = {}
|
|
103
|
+
self.RightClickMenu = right_click_menu
|
|
104
|
+
self.FloatValues = float_values
|
|
105
|
+
self.BorderWidth = border_width
|
|
106
|
+
action = action if action is not None else k
|
|
107
|
+
pad = pad if pad is not None else p
|
|
108
|
+
self.expand_x = expand_x
|
|
109
|
+
self.expand_y = expand_y
|
|
110
|
+
self.motion_events = motion_events
|
|
111
|
+
|
|
112
|
+
super().__init__(
|
|
113
|
+
ELEM_TYPE_GRAPH,
|
|
114
|
+
background_color=background_color,
|
|
115
|
+
size=canvas_size,
|
|
116
|
+
pad=pad,
|
|
117
|
+
action=action,
|
|
118
|
+
ke_upar=ke_upar,
|
|
119
|
+
nazar=nazar,
|
|
120
|
+
metadata=metadata,
|
|
121
|
+
)
|
|
122
|
+
return
|
|
123
|
+
|
|
124
|
+
def _convert_xy_to_canvas_xy(self, x_in, y_in):
|
|
125
|
+
"""
|
|
126
|
+
Not user callable. Used to convert user's coordinates into the ones used by tkinter
|
|
127
|
+
:param x_in: The x coordinate to convert
|
|
128
|
+
:type x_in: int | float
|
|
129
|
+
:param y_in: The y coordinate to convert
|
|
130
|
+
:type y_in: int | float
|
|
131
|
+
:return: (int, int) The converted canvas coordinates
|
|
132
|
+
:rtype: (int, int)
|
|
133
|
+
"""
|
|
134
|
+
if None in (x_in, y_in):
|
|
135
|
+
return None, None
|
|
136
|
+
try:
|
|
137
|
+
scale_x = (self.CanvasSize[0] - 0) / (self.TopRight[0] - self.BottomLeft[0])
|
|
138
|
+
scale_y = (0 - self.CanvasSize[1]) / (self.TopRight[1] - self.BottomLeft[1])
|
|
139
|
+
except:
|
|
140
|
+
scale_x = scale_y = 0
|
|
141
|
+
|
|
142
|
+
new_x = 0 + scale_x * (x_in - self.BottomLeft[0])
|
|
143
|
+
new_y = self.CanvasSize[1] + scale_y * (y_in - self.BottomLeft[1])
|
|
144
|
+
return new_x, new_y
|
|
145
|
+
|
|
146
|
+
def _convert_canvas_xy_to_xy(self, x_in, y_in):
|
|
147
|
+
"""
|
|
148
|
+
Not user callable. Used to convert tkinter Canvas coords into user's coordinates
|
|
149
|
+
|
|
150
|
+
:param x_in: The x coordinate in canvas coordinates
|
|
151
|
+
:type x_in: (int)
|
|
152
|
+
:param y_in: (int) The y coordinate in canvas coordinates
|
|
153
|
+
:type y_in:
|
|
154
|
+
:return: The converted USER coordinates
|
|
155
|
+
:rtype: (int, int) | Tuple[float, float]
|
|
156
|
+
"""
|
|
157
|
+
if None in (x_in, y_in):
|
|
158
|
+
return None, None
|
|
159
|
+
scale_x = (self.CanvasSize[0] - 0) / (self.TopRight[0] - self.BottomLeft[0])
|
|
160
|
+
scale_y = (0 - self.CanvasSize[1]) / (self.TopRight[1] - self.BottomLeft[1])
|
|
161
|
+
|
|
162
|
+
new_x = x_in / scale_x + self.BottomLeft[0]
|
|
163
|
+
new_y = (y_in - self.CanvasSize[1]) / scale_y + self.BottomLeft[1]
|
|
164
|
+
if self.FloatValues:
|
|
165
|
+
return new_x, new_y
|
|
166
|
+
else:
|
|
167
|
+
return floor(new_x), floor(new_y)
|
|
168
|
+
|
|
169
|
+
def draw_line(self, point_from, point_to, color='black', width=1):
|
|
170
|
+
"""
|
|
171
|
+
Draws a line from one point to another point using USER'S coordinates. Can set the color and width of line
|
|
172
|
+
:param point_from: Starting point for line
|
|
173
|
+
:type point_from: (int, int) | Tuple[float, float]
|
|
174
|
+
:param point_to: Ending point for line
|
|
175
|
+
:type point_to: (int, int) | Tuple[float, float]
|
|
176
|
+
:param color: Color of the line
|
|
177
|
+
:type color: (str)
|
|
178
|
+
:param width: width of line in pixels
|
|
179
|
+
:type width: (int)
|
|
180
|
+
:return: id returned from tktiner or None if user closed the window. id is used when you
|
|
181
|
+
:rtype: int | None
|
|
182
|
+
"""
|
|
183
|
+
if point_from == (None, None):
|
|
184
|
+
return
|
|
185
|
+
converted_point_from = self._convert_xy_to_canvas_xy(point_from[0], point_from[1])
|
|
186
|
+
converted_point_to = self._convert_xy_to_canvas_xy(point_to[0], point_to[1])
|
|
187
|
+
if self._TKCanvas2 is None:
|
|
188
|
+
print('*** WARNING - The Graph element has not been finalized and cannot be drawn upon ***')
|
|
189
|
+
print('Call Window.Finalize() prior to this operation')
|
|
190
|
+
return None
|
|
191
|
+
try: # in case window was closed with an X
|
|
192
|
+
id = self._TKCanvas2.create_line(converted_point_from, converted_point_to, width=width, fill=color)
|
|
193
|
+
except:
|
|
194
|
+
id = None
|
|
195
|
+
return id
|
|
196
|
+
|
|
197
|
+
def draw_lines(self, points, color='black', width=1):
|
|
198
|
+
"""
|
|
199
|
+
Draw a series of lines given list of points
|
|
200
|
+
|
|
201
|
+
:param points: list of points that define the polygon
|
|
202
|
+
:type points: List[(int, int) | Tuple[float, float]]
|
|
203
|
+
:param color: Color of the line
|
|
204
|
+
:type color: (str)
|
|
205
|
+
:param width: width of line in pixels
|
|
206
|
+
:type width: (int)
|
|
207
|
+
:return: id returned from tktiner or None if user closed the window. id is used when you
|
|
208
|
+
:rtype: int | None
|
|
209
|
+
"""
|
|
210
|
+
converted_points = [self._convert_xy_to_canvas_xy(point[0], point[1]) for point in points]
|
|
211
|
+
|
|
212
|
+
try: # in case window was closed with an X
|
|
213
|
+
id = self._TKCanvas2.create_line(*converted_points, width=width, fill=color)
|
|
214
|
+
except:
|
|
215
|
+
if self._TKCanvas2 is None:
|
|
216
|
+
print('*** WARNING - The Graph element has not been finalized and cannot be drawn upon ***')
|
|
217
|
+
print('Call Window.Finalize() prior to this operation')
|
|
218
|
+
id = None
|
|
219
|
+
return id
|
|
220
|
+
|
|
221
|
+
def draw_point(self, point, size=2, color='black'):
|
|
222
|
+
"""
|
|
223
|
+
Draws a "dot" at the point you specify using the USER'S coordinate system
|
|
224
|
+
:param point: Center location using USER'S coordinate system
|
|
225
|
+
:type point: (int, int) | Tuple[float, float]
|
|
226
|
+
:param size: Radius? (Or is it the diameter?) in user's coordinate values.
|
|
227
|
+
:type size: int | float
|
|
228
|
+
:param color: color of the point to draw
|
|
229
|
+
:type color: (str)
|
|
230
|
+
:return: id returned from tkinter that you'll need if you want to manipulate the point
|
|
231
|
+
:rtype: int | None
|
|
232
|
+
"""
|
|
233
|
+
if point == (None, None):
|
|
234
|
+
return
|
|
235
|
+
converted_point = self._convert_xy_to_canvas_xy(point[0], point[1])
|
|
236
|
+
size_converted = self._convert_xy_to_canvas_xy(point[0] + size, point[1])
|
|
237
|
+
size = size_converted[0] - converted_point[0]
|
|
238
|
+
if self._TKCanvas2 is None:
|
|
239
|
+
print('*** WARNING - The Graph element has not been finalized and cannot be drawn upon ***')
|
|
240
|
+
print('Call Window.Finalize() prior to this operation')
|
|
241
|
+
return None
|
|
242
|
+
try: # needed in case window was closed with an X
|
|
243
|
+
point1 = converted_point[0] - size // 2, converted_point[1] - size // 2
|
|
244
|
+
point2 = converted_point[0] + size // 2, converted_point[1] + size // 2
|
|
245
|
+
id = self._TKCanvas2.create_oval(point1[0], point1[1], point2[0], point2[1], width=0, fill=color, outline=color)
|
|
246
|
+
except:
|
|
247
|
+
id = None
|
|
248
|
+
return id
|
|
249
|
+
|
|
250
|
+
def draw_circle(self, center_location, radius, fill_color=None, line_color='black', line_width=1):
|
|
251
|
+
"""
|
|
252
|
+
Draws a circle, cenetered at the location provided. Can set the fill and outline colors
|
|
253
|
+
:param center_location: Center location using USER'S coordinate system
|
|
254
|
+
:type center_location: (int, int) | Tuple[float, float]
|
|
255
|
+
:param radius: Radius in user's coordinate values.
|
|
256
|
+
:type radius: int | float
|
|
257
|
+
:param fill_color: color of the point to draw
|
|
258
|
+
:type fill_color: (str)
|
|
259
|
+
:param line_color: color of the outer line that goes around the circle (sorry, can't set thickness)
|
|
260
|
+
:type line_color: (str)
|
|
261
|
+
:param line_width: width of the line around the circle, the outline, in pixels
|
|
262
|
+
:type line_width: (int)
|
|
263
|
+
:return: id returned from tkinter that you'll need if you want to manipulate the circle
|
|
264
|
+
:rtype: int | None
|
|
265
|
+
"""
|
|
266
|
+
if center_location == (None, None):
|
|
267
|
+
return
|
|
268
|
+
converted_point = self._convert_xy_to_canvas_xy(center_location[0], center_location[1])
|
|
269
|
+
radius_converted = self._convert_xy_to_canvas_xy(center_location[0] + radius, center_location[1])
|
|
270
|
+
radius = radius_converted[0] - converted_point[0]
|
|
271
|
+
# radius = radius_converted[1]-5
|
|
272
|
+
if self._TKCanvas2 is None:
|
|
273
|
+
print('*** WARNING - The Graph element has not been finalized and cannot be drawn upon ***')
|
|
274
|
+
print('Call Window.Finalize() prior to this operation')
|
|
275
|
+
return None
|
|
276
|
+
try: # needed in case the window was closed with an X
|
|
277
|
+
id = self._TKCanvas2.create_oval(
|
|
278
|
+
int(converted_point[0]) - int(radius),
|
|
279
|
+
int(converted_point[1]) - int(radius),
|
|
280
|
+
int(converted_point[0]) + int(radius),
|
|
281
|
+
int(converted_point[1]) + int(radius),
|
|
282
|
+
fill=fill_color,
|
|
283
|
+
outline=line_color,
|
|
284
|
+
width=line_width,
|
|
285
|
+
)
|
|
286
|
+
except:
|
|
287
|
+
id = None
|
|
288
|
+
return id
|
|
289
|
+
|
|
290
|
+
def draw_oval(self, top_left, bottom_right, fill_color=None, line_color=None, line_width=1):
|
|
291
|
+
"""
|
|
292
|
+
Draws an oval based on coordinates in user coordinate system. Provide the location of a "bounding rectangle"
|
|
293
|
+
:param top_left: the top left point of bounding rectangle
|
|
294
|
+
:type top_left: (int, int) | Tuple[float, float]
|
|
295
|
+
:param bottom_right: the bottom right point of bounding rectangle
|
|
296
|
+
:type bottom_right: (int, int) | Tuple[float, float]
|
|
297
|
+
:param fill_color: color of the interrior
|
|
298
|
+
:type fill_color: (str)
|
|
299
|
+
:param line_color: color of outline of oval
|
|
300
|
+
:type line_color: (str)
|
|
301
|
+
:param line_width: width of the line around the oval, the outline, in pixels
|
|
302
|
+
:type line_width: (int)
|
|
303
|
+
:return: id returned from tkinter that you'll need if you want to manipulate the oval
|
|
304
|
+
:rtype: int | None
|
|
305
|
+
"""
|
|
306
|
+
converted_top_left = self._convert_xy_to_canvas_xy(top_left[0], top_left[1])
|
|
307
|
+
converted_bottom_right = self._convert_xy_to_canvas_xy(bottom_right[0], bottom_right[1])
|
|
308
|
+
if self._TKCanvas2 is None:
|
|
309
|
+
print('*** WARNING - The Graph element has not been finalized and cannot be drawn upon ***')
|
|
310
|
+
print('Call Window.Finalize() prior to this operation')
|
|
311
|
+
return None
|
|
312
|
+
try: # in case windows close with X
|
|
313
|
+
id = self._TKCanvas2.create_oval(
|
|
314
|
+
converted_top_left[0],
|
|
315
|
+
converted_top_left[1],
|
|
316
|
+
converted_bottom_right[0],
|
|
317
|
+
converted_bottom_right[1],
|
|
318
|
+
fill=fill_color,
|
|
319
|
+
outline=line_color,
|
|
320
|
+
width=line_width,
|
|
321
|
+
)
|
|
322
|
+
except:
|
|
323
|
+
id = None
|
|
324
|
+
|
|
325
|
+
return id
|
|
326
|
+
|
|
327
|
+
def draw_arc(self, top_left, bottom_right, extent, start_angle, style=None, arc_color='black', line_width=1, fill_color=None):
|
|
328
|
+
"""
|
|
329
|
+
Draws different types of arcs. Uses a "bounding box" to define location
|
|
330
|
+
:param top_left: the top left point of bounding rectangle
|
|
331
|
+
:type top_left: (int, int) | Tuple[float, float]
|
|
332
|
+
:param bottom_right: the bottom right point of bounding rectangle
|
|
333
|
+
:type bottom_right: (int, int) | Tuple[float, float]
|
|
334
|
+
:param extent: Andle to end drawing. Used in conjunction with start_angle
|
|
335
|
+
:type extent: (float)
|
|
336
|
+
:param start_angle: Angle to begin drawing. Used in conjunction with extent
|
|
337
|
+
:type start_angle: (float)
|
|
338
|
+
:param style: Valid choices are One of these Style strings- 'pieslice', 'chord', 'arc', 'first', 'last', 'butt', 'projecting', 'round', 'bevel', 'miter'
|
|
339
|
+
:type style: (str)
|
|
340
|
+
:param arc_color: color to draw arc with
|
|
341
|
+
:type arc_color: (str)
|
|
342
|
+
:param fill_color: color to fill the area
|
|
343
|
+
:type fill_color: (str)
|
|
344
|
+
:return: id returned from tkinter that you'll need if you want to manipulate the arc
|
|
345
|
+
:rtype: int | None
|
|
346
|
+
"""
|
|
347
|
+
converted_top_left = self._convert_xy_to_canvas_xy(top_left[0], top_left[1])
|
|
348
|
+
converted_bottom_right = self._convert_xy_to_canvas_xy(bottom_right[0], bottom_right[1])
|
|
349
|
+
tkstyle = tk.PIESLICE if style is None else style
|
|
350
|
+
if self._TKCanvas2 is None:
|
|
351
|
+
print('*** WARNING - The Graph element has not been finalized and cannot be drawn upon ***')
|
|
352
|
+
print('Call Window.Finalize() prior to this operation')
|
|
353
|
+
return None
|
|
354
|
+
try: # in case closed with X
|
|
355
|
+
id = self._TKCanvas2.create_arc(
|
|
356
|
+
converted_top_left[0],
|
|
357
|
+
converted_top_left[1],
|
|
358
|
+
converted_bottom_right[0],
|
|
359
|
+
converted_bottom_right[1],
|
|
360
|
+
extent=extent,
|
|
361
|
+
start=start_angle,
|
|
362
|
+
style=tkstyle,
|
|
363
|
+
outline=arc_color,
|
|
364
|
+
width=line_width,
|
|
365
|
+
fill=fill_color,
|
|
366
|
+
)
|
|
367
|
+
except Exception as e:
|
|
368
|
+
print('Error encountered drawing arc.', e)
|
|
369
|
+
id = None
|
|
370
|
+
return id
|
|
371
|
+
|
|
372
|
+
def draw_rectangle(self, top_left, bottom_right, fill_color=None, line_color=None, line_width=None):
|
|
373
|
+
"""
|
|
374
|
+
Draw a rectangle given 2 points. Can control the line and fill colors
|
|
375
|
+
|
|
376
|
+
:param top_left: the top left point of rectangle
|
|
377
|
+
:type top_left: (int, int) | Tuple[float, float]
|
|
378
|
+
:param bottom_right: the bottom right point of rectangle
|
|
379
|
+
:type bottom_right: (int, int) | Tuple[float, float]
|
|
380
|
+
:param fill_color: color of the interior
|
|
381
|
+
:type fill_color: (str)
|
|
382
|
+
:param line_color: color of outline
|
|
383
|
+
:type line_color: (str)
|
|
384
|
+
:param line_width: width of the line in pixels
|
|
385
|
+
:type line_width: (int)
|
|
386
|
+
:return: int | None id returned from tkinter that you'll need if you want to manipulate the rectangle
|
|
387
|
+
:rtype: int | None
|
|
388
|
+
"""
|
|
389
|
+
|
|
390
|
+
converted_top_left = self._convert_xy_to_canvas_xy(top_left[0], top_left[1])
|
|
391
|
+
converted_bottom_right = self._convert_xy_to_canvas_xy(bottom_right[0], bottom_right[1])
|
|
392
|
+
if self._TKCanvas2 is None:
|
|
393
|
+
print('*** WARNING - The Graph element has not been finalized and cannot be drawn upon ***')
|
|
394
|
+
print('Call Window.Finalize() prior to this operation')
|
|
395
|
+
return None
|
|
396
|
+
if line_width is None:
|
|
397
|
+
line_width = 1
|
|
398
|
+
try: # in case closed with X
|
|
399
|
+
id = self._TKCanvas2.create_rectangle(
|
|
400
|
+
converted_top_left[0],
|
|
401
|
+
converted_top_left[1],
|
|
402
|
+
converted_bottom_right[0],
|
|
403
|
+
converted_bottom_right[1],
|
|
404
|
+
fill=fill_color,
|
|
405
|
+
outline=line_color,
|
|
406
|
+
width=line_width,
|
|
407
|
+
)
|
|
408
|
+
except:
|
|
409
|
+
id = None
|
|
410
|
+
return id
|
|
411
|
+
|
|
412
|
+
def draw_polygon(self, points, fill_color=None, line_color=None, line_width=None):
|
|
413
|
+
"""
|
|
414
|
+
Draw a polygon given list of points
|
|
415
|
+
|
|
416
|
+
:param points: list of points that define the polygon
|
|
417
|
+
:type points: List[(int, int) | Tuple[float, float]]
|
|
418
|
+
:param fill_color: color of the interior
|
|
419
|
+
:type fill_color: (str)
|
|
420
|
+
:param line_color: color of outline
|
|
421
|
+
:type line_color: (str)
|
|
422
|
+
:param line_width: width of the line in pixels
|
|
423
|
+
:type line_width: (int)
|
|
424
|
+
:return: id returned from tkinter that you'll need if you want to manipulate the rectangle
|
|
425
|
+
:rtype: int | None
|
|
426
|
+
"""
|
|
427
|
+
|
|
428
|
+
converted_points = [self._convert_xy_to_canvas_xy(point[0], point[1]) for point in points]
|
|
429
|
+
if self._TKCanvas2 is None:
|
|
430
|
+
print('*** WARNING - The Graph element has not been finalized and cannot be drawn upon ***')
|
|
431
|
+
print('Call Window.Finalize() prior to this operation')
|
|
432
|
+
return None
|
|
433
|
+
try: # in case closed with X
|
|
434
|
+
id = self._TKCanvas2.create_polygon(converted_points, fill=fill_color, outline=line_color, width=line_width)
|
|
435
|
+
except:
|
|
436
|
+
id = None
|
|
437
|
+
return id
|
|
438
|
+
|
|
439
|
+
def draw_text(self, text, location, color='black', font=None, angle=0, text_location=TEXT_LOCATION_CENTER):
|
|
440
|
+
"""
|
|
441
|
+
Draw some text on your graph. This is how you label graph number lines for example
|
|
442
|
+
|
|
443
|
+
:param text: text to display
|
|
444
|
+
:type text: (Any)
|
|
445
|
+
:param location: location to place first letter
|
|
446
|
+
:type location: (int, int) | Tuple[float, float]
|
|
447
|
+
:param color: text color
|
|
448
|
+
:type color: (str)
|
|
449
|
+
:param font: specifies the font family, size, etc. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike
|
|
450
|
+
:type font: (str or (str, int[, str]) or None)
|
|
451
|
+
:param angle: Angle 0 to 360 to draw the text. Zero represents horizontal text
|
|
452
|
+
:type angle: (float)
|
|
453
|
+
:param text_location: "anchor" location for the text. Values start with TEXT_LOCATION_
|
|
454
|
+
:type text_location: (enum)
|
|
455
|
+
:return: id returned from tkinter that you'll need if you want to manipulate the text
|
|
456
|
+
:rtype: int | None
|
|
457
|
+
"""
|
|
458
|
+
text = str(text)
|
|
459
|
+
if location == (None, None):
|
|
460
|
+
return
|
|
461
|
+
converted_point = self._convert_xy_to_canvas_xy(location[0], location[1])
|
|
462
|
+
if self._TKCanvas2 is None:
|
|
463
|
+
print('*** WARNING - The Graph element has not been finalized and cannot be drawn upon ***')
|
|
464
|
+
print('Call Window.Finalize() prior to this operation')
|
|
465
|
+
return None
|
|
466
|
+
try: # in case closed with X
|
|
467
|
+
id = self._TKCanvas2.create_text(
|
|
468
|
+
converted_point[0],
|
|
469
|
+
converted_point[1],
|
|
470
|
+
text=text,
|
|
471
|
+
font=font,
|
|
472
|
+
fill=color,
|
|
473
|
+
angle=angle,
|
|
474
|
+
anchor=text_location,
|
|
475
|
+
)
|
|
476
|
+
except:
|
|
477
|
+
id = None
|
|
478
|
+
return id
|
|
479
|
+
|
|
480
|
+
def draw_image(self, filename=None, data=None, location=(None, None)):
|
|
481
|
+
"""
|
|
482
|
+
Places an image onto your canvas. It's a really important method for this element as it enables so much
|
|
483
|
+
|
|
484
|
+
:param filename: if image is in a file, path and filename for the image. (GIF and PNG only!)
|
|
485
|
+
:type filename: (str)
|
|
486
|
+
:param data: if image is in Base64 format or raw? format then use instead of filename
|
|
487
|
+
:type data: str | bytes
|
|
488
|
+
:param location: the (x,y) location to place image's top left corner
|
|
489
|
+
:type location: (int, int) | Tuple[float, float]
|
|
490
|
+
:return: id returned from tkinter that you'll need if you want to manipulate the image
|
|
491
|
+
:rtype: int | None
|
|
492
|
+
"""
|
|
493
|
+
if location == (None, None):
|
|
494
|
+
return
|
|
495
|
+
if filename is not None:
|
|
496
|
+
image = tk.PhotoImage(file=filename)
|
|
497
|
+
elif data is not None:
|
|
498
|
+
# if type(data) is bytes:
|
|
499
|
+
try:
|
|
500
|
+
image = tk.PhotoImage(data=data)
|
|
501
|
+
except:
|
|
502
|
+
return None # an error likely means the window has closed so exit
|
|
503
|
+
converted_point = self._convert_xy_to_canvas_xy(location[0], location[1])
|
|
504
|
+
if self._TKCanvas2 is None:
|
|
505
|
+
print('*** WARNING - The Graph element has not been finalized and cannot be drawn upon ***')
|
|
506
|
+
print('Call Window.Finalize() prior to this operation')
|
|
507
|
+
return None
|
|
508
|
+
try: # in case closed with X
|
|
509
|
+
id = self._TKCanvas2.create_image(converted_point, image=image, anchor=tk.NW)
|
|
510
|
+
self.Images[id] = image
|
|
511
|
+
except:
|
|
512
|
+
id = None
|
|
513
|
+
return id
|
|
514
|
+
|
|
515
|
+
def erase(self):
|
|
516
|
+
"""
|
|
517
|
+
Erase the Graph - Removes all figures previously "drawn" using the Graph methods (e.g. DrawText)
|
|
518
|
+
"""
|
|
519
|
+
if self._TKCanvas2 is None:
|
|
520
|
+
print('*** WARNING - The Graph element has not been finalized and cannot be drawn upon ***')
|
|
521
|
+
print('Call Window.Finalize() prior to this operation')
|
|
522
|
+
return None
|
|
523
|
+
self.Images = {}
|
|
524
|
+
try: # in case window was closed with X
|
|
525
|
+
self._TKCanvas2.delete('all')
|
|
526
|
+
except:
|
|
527
|
+
pass
|
|
528
|
+
|
|
529
|
+
def delete_figure(self, id):
|
|
530
|
+
"""
|
|
531
|
+
Remove from the Graph the figure represented by id. The id is given to you anytime you call a drawing primitive
|
|
532
|
+
|
|
533
|
+
:param id: the id returned to you when calling one of the drawing methods
|
|
534
|
+
:type id: (int)
|
|
535
|
+
"""
|
|
536
|
+
try:
|
|
537
|
+
self._TKCanvas2.delete(id)
|
|
538
|
+
except:
|
|
539
|
+
print(f'DeleteFigure - bad ID {id}')
|
|
540
|
+
try:
|
|
541
|
+
del self.Images[id] # in case was an image. If wasn't an image, then will get exception
|
|
542
|
+
except:
|
|
543
|
+
pass
|
|
544
|
+
|
|
545
|
+
def badlo(self, background_color=None, nazar=None):
|
|
546
|
+
"""
|
|
547
|
+
Changes some of the settings for the Graph Element. Must call `Window.Read` or `Window.Finalize` prior
|
|
548
|
+
|
|
549
|
+
Changes will not be nazar in your window until you call window.read or window.refresh.
|
|
550
|
+
|
|
551
|
+
If you badlo visibility, your element may MOVE. If you want it to remain stationary, use the "layout helper"
|
|
552
|
+
function "pin" to ensure your element is "pinned" to that location in your layout so that it returns there
|
|
553
|
+
when made nazar.
|
|
554
|
+
|
|
555
|
+
:param background_color: color of background
|
|
556
|
+
:type background_color: ???
|
|
557
|
+
:param nazar: control visibility of element
|
|
558
|
+
:type nazar: (bool)
|
|
559
|
+
"""
|
|
560
|
+
if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow
|
|
561
|
+
return
|
|
562
|
+
|
|
563
|
+
if self._this_elements_window_closed():
|
|
564
|
+
_error_popup_with_traceback('Error in Graph.badlo - The window was closed')
|
|
565
|
+
return
|
|
566
|
+
|
|
567
|
+
if background_color is not None and background_color != COLOR_SYSTEM_DEFAULT:
|
|
568
|
+
self._TKCanvas2.configure(background=background_color)
|
|
569
|
+
|
|
570
|
+
if nazar is False:
|
|
571
|
+
self._pack_forget_save_settings()
|
|
572
|
+
elif nazar is True:
|
|
573
|
+
self._pack_restore_settings()
|
|
574
|
+
|
|
575
|
+
if nazar is not None:
|
|
576
|
+
self._nazar = nazar
|
|
577
|
+
|
|
578
|
+
def move(self, x_direction, y_direction):
|
|
579
|
+
"""
|
|
580
|
+
Moves the entire drawing area (the canvas) by some delta from the current position. Units are indicated in your coordinate system indicated number of ticks in your coordinate system
|
|
581
|
+
|
|
582
|
+
:param x_direction: how far to move in the "X" direction in your coordinates
|
|
583
|
+
:type x_direction: int | float
|
|
584
|
+
:param y_direction: how far to move in the "Y" direction in your coordinates
|
|
585
|
+
:type y_direction: int | float
|
|
586
|
+
"""
|
|
587
|
+
zero_converted = self._convert_xy_to_canvas_xy(0, 0)
|
|
588
|
+
shift_converted = self._convert_xy_to_canvas_xy(x_direction, y_direction)
|
|
589
|
+
shift_amount = (shift_converted[0] - zero_converted[0], shift_converted[1] - zero_converted[1])
|
|
590
|
+
if self._TKCanvas2 is None:
|
|
591
|
+
print('*** WARNING - The Graph element has not been finalized and cannot be drawn upon ***')
|
|
592
|
+
print('Call Window.Finalize() prior to this operation')
|
|
593
|
+
return None
|
|
594
|
+
self._TKCanvas2.move('all', shift_amount[0], shift_amount[1])
|
|
595
|
+
|
|
596
|
+
def move_figure(self, figure, x_direction, y_direction):
|
|
597
|
+
"""
|
|
598
|
+
Moves a previously drawn figure using a "delta" from current position
|
|
599
|
+
|
|
600
|
+
:param figure: Previously obtained figure-id. These are returned from all Draw methods
|
|
601
|
+
:type figure: (id)
|
|
602
|
+
:param x_direction: delta to apply to position in the X direction
|
|
603
|
+
:type x_direction: int | float
|
|
604
|
+
:param y_direction: delta to apply to position in the Y direction
|
|
605
|
+
:type y_direction: int | float
|
|
606
|
+
"""
|
|
607
|
+
zero_converted = self._convert_xy_to_canvas_xy(0, 0)
|
|
608
|
+
shift_converted = self._convert_xy_to_canvas_xy(x_direction, y_direction)
|
|
609
|
+
shift_amount = (shift_converted[0] - zero_converted[0], shift_converted[1] - zero_converted[1])
|
|
610
|
+
if figure is None:
|
|
611
|
+
print('* move_figure warning - your figure is None *')
|
|
612
|
+
return None
|
|
613
|
+
self._TKCanvas2.move(figure, shift_amount[0], shift_amount[1])
|
|
614
|
+
|
|
615
|
+
def relocate_figure(self, figure, x, y):
|
|
616
|
+
"""
|
|
617
|
+
Move a previously made figure to an arbitrary (x,y) location. This differs from the Move methods because it
|
|
618
|
+
uses absolute coordinates versus relative for Move
|
|
619
|
+
|
|
620
|
+
:param figure: Previously obtained figure-id. These are returned from all Draw methods
|
|
621
|
+
:type figure: (id)
|
|
622
|
+
:param x: location on X axis (in user coords) to move the upper left corner of the figure
|
|
623
|
+
:type x: int | float
|
|
624
|
+
:param y: location on Y axis (in user coords) to move the upper left corner of the figure
|
|
625
|
+
:type y: int | float
|
|
626
|
+
"""
|
|
627
|
+
|
|
628
|
+
# zero_converted = self._convert_xy_to_canvas_xy(0, 0)
|
|
629
|
+
shift_converted = self._convert_xy_to_canvas_xy(x, y)
|
|
630
|
+
# shift_amount = (shift_converted[0] - zero_converted[0], shift_converted[1] - zero_converted[1])
|
|
631
|
+
if figure is None:
|
|
632
|
+
print('*** WARNING - Your figure is None. It most likely means your did not Finalize your Window ***')
|
|
633
|
+
print('Call Window.Finalize() prior to all graph operations')
|
|
634
|
+
return None
|
|
635
|
+
xy = self._TKCanvas2.coords(figure)
|
|
636
|
+
self._TKCanvas2.move(figure, shift_converted[0] - xy[0], shift_converted[1] - xy[1])
|
|
637
|
+
|
|
638
|
+
def send_figure_to_back(self, figure):
|
|
639
|
+
"""
|
|
640
|
+
Changes Z-order of figures on the Graph. Sends the indicated figure to the back of all other drawn figures
|
|
641
|
+
|
|
642
|
+
:param figure: value returned by tkinter when creating the figure / drawing
|
|
643
|
+
:type figure: (int)
|
|
644
|
+
"""
|
|
645
|
+
self.TKCanvas.tag_lower(figure) # move figure to the "bottom" of all other figure
|
|
646
|
+
|
|
647
|
+
def bring_figure_to_front(self, figure):
|
|
648
|
+
"""
|
|
649
|
+
Changes Z-order of figures on the Graph. Brings the indicated figure to the front of all other drawn figures
|
|
650
|
+
|
|
651
|
+
:param figure: value returned by tkinter when creating the figure / drawing
|
|
652
|
+
:type figure: (int)
|
|
653
|
+
"""
|
|
654
|
+
self.TKCanvas.tag_raise(figure) # move figure to the "top" of all other figures
|
|
655
|
+
|
|
656
|
+
def get_figures_at_location(self, location):
|
|
657
|
+
"""
|
|
658
|
+
Returns a list of figures located at a particular x,y location within the Graph
|
|
659
|
+
|
|
660
|
+
:param location: point to check
|
|
661
|
+
:type location: (int, int) | Tuple[float, float]
|
|
662
|
+
:return: a list of previously drawn "Figures" (returned from the drawing primitives)
|
|
663
|
+
:rtype: List[int]
|
|
664
|
+
"""
|
|
665
|
+
x, y = self._convert_xy_to_canvas_xy(location[0], location[1])
|
|
666
|
+
ids = self.TKCanvas.find_overlapping(x, y, x, y)
|
|
667
|
+
return ids
|
|
668
|
+
|
|
669
|
+
def get_bounding_box(self, figure):
|
|
670
|
+
"""
|
|
671
|
+
Given a figure, returns the upper left and lower right bounding box coordinates
|
|
672
|
+
|
|
673
|
+
:param figure: a previously drawing figure
|
|
674
|
+
:type figure: object
|
|
675
|
+
:return: upper left x, upper left y, lower right x, lower right y
|
|
676
|
+
:rtype: Tuple[int, int, int, int] | Tuple[float, float, float, float]
|
|
677
|
+
"""
|
|
678
|
+
box = self.TKCanvas.bbox(figure)
|
|
679
|
+
top_left = self._convert_canvas_xy_to_xy(box[0], box[1])
|
|
680
|
+
bottom_right = self._convert_canvas_xy_to_xy(box[2], box[3])
|
|
681
|
+
return top_left, bottom_right
|
|
682
|
+
|
|
683
|
+
def change_coordinates(self, graph_bottom_left, graph_top_right):
|
|
684
|
+
"""
|
|
685
|
+
Changes the corrdinate system to a new one. The same 2 points in space are used to define the coorinate
|
|
686
|
+
system - the bottom left and the top right values of your graph.
|
|
687
|
+
|
|
688
|
+
:param graph_bottom_left: The bottoms left corner of your coordinate system
|
|
689
|
+
:type graph_bottom_left: (int, int) (x,y)
|
|
690
|
+
:param graph_top_right: The top right corner of your coordinate system
|
|
691
|
+
:type graph_top_right: (int, int) (x,y)
|
|
692
|
+
"""
|
|
693
|
+
self.BottomLeft = graph_bottom_left
|
|
694
|
+
self.TopRight = graph_top_right
|
|
695
|
+
|
|
696
|
+
@property
|
|
697
|
+
def tk_canvas(self):
|
|
698
|
+
"""
|
|
699
|
+
Returns the underlying tkiner Canvas widget
|
|
700
|
+
|
|
701
|
+
:return: The tkinter canvas widget
|
|
702
|
+
:rtype: (tk.Canvas)
|
|
703
|
+
"""
|
|
704
|
+
if self._TKCanvas2 is None:
|
|
705
|
+
print('*** Did you forget to call Finalize()? Your code should look something like: ***')
|
|
706
|
+
print('*** form = sg.Window("My Form").Layout(layout).Finalize() ***')
|
|
707
|
+
return self._TKCanvas2
|
|
708
|
+
|
|
709
|
+
# button release callback
|
|
710
|
+
def button_release_call_back(self, action):
|
|
711
|
+
"""
|
|
712
|
+
Not a user callable method. Used to get Graph click events. Called by tkinter when button is released
|
|
713
|
+
|
|
714
|
+
:param action: (action) action info from tkinter. Note not used in this method
|
|
715
|
+
:type action:
|
|
716
|
+
"""
|
|
717
|
+
if not self.DragSubmits:
|
|
718
|
+
return # only report mouse up for drag operations
|
|
719
|
+
self.ClickPosition = self._convert_canvas_xy_to_xy(action.x, action.y)
|
|
720
|
+
self.ParentForm.LastButtonClickedWasRealtime = False
|
|
721
|
+
if self.Key is not None:
|
|
722
|
+
self.ParentForm.LastButtonClicked = self.Key
|
|
723
|
+
else:
|
|
724
|
+
self.ParentForm.LastButtonClicked = '__GRAPH__' # need to put something rather than None
|
|
725
|
+
_exit_mainloop(self.ParentForm)
|
|
726
|
+
if isinstance(self.ParentForm.LastButtonClicked, str):
|
|
727
|
+
self.ParentForm.LastButtonClicked = self.ParentForm.LastButtonClicked + '+UP'
|
|
728
|
+
else:
|
|
729
|
+
self.ParentForm.LastButtonClicked = (self.ParentForm.LastButtonClicked, '+UP')
|
|
730
|
+
self.MouseButtonDown = False
|
|
731
|
+
|
|
732
|
+
# button callback
|
|
733
|
+
def button_press_call_back(self, action):
|
|
734
|
+
"""
|
|
735
|
+
Not a user callable method. Used to get Graph click events. Called by tkinter when button is released
|
|
736
|
+
|
|
737
|
+
:param action: (action) action info from tkinter. Contains the x and y coordinates of a click
|
|
738
|
+
:type action:
|
|
739
|
+
"""
|
|
740
|
+
|
|
741
|
+
self.ClickPosition = self._convert_canvas_xy_to_xy(action.x, action.y)
|
|
742
|
+
self.ParentForm.LastButtonClickedWasRealtime = self.DragSubmits
|
|
743
|
+
if self.Key is not None:
|
|
744
|
+
self.ParentForm.LastButtonClicked = self.Key
|
|
745
|
+
else:
|
|
746
|
+
self.ParentForm.LastButtonClicked = '__GRAPH__' # need to put something rather than None
|
|
747
|
+
_exit_mainloop(self.ParentForm)
|
|
748
|
+
self.MouseButtonDown = True
|
|
749
|
+
|
|
750
|
+
def _update_position_for_returned_values(self, action):
|
|
751
|
+
"""
|
|
752
|
+
Updates the variable that's used when the values dictionary is returned from a window read.
|
|
753
|
+
|
|
754
|
+
Not called by the user. It's called from another method/function that tkinter calledback
|
|
755
|
+
|
|
756
|
+
:param action: (action) action info from tkinter. Contains the x and y coordinates of a click
|
|
757
|
+
:type action:
|
|
758
|
+
"""
|
|
759
|
+
"""
|
|
760
|
+
Updates the variable that's used when the values dictionary is returned from a window read.
|
|
761
|
+
|
|
762
|
+
Not called by the user. It's called from another method/function that tkinter calledback
|
|
763
|
+
|
|
764
|
+
:param action: (action) action info from tkinter. Contains the x and y coordinates of a click
|
|
765
|
+
:type action:
|
|
766
|
+
"""
|
|
767
|
+
|
|
768
|
+
self.ClickPosition = self._convert_canvas_xy_to_xy(action.x, action.y)
|
|
769
|
+
|
|
770
|
+
# button callback
|
|
771
|
+
def motion_call_back(self, action):
|
|
772
|
+
"""
|
|
773
|
+
Not a user callable method. Used to get Graph mouse motion events. Called by tkinter when mouse moved
|
|
774
|
+
|
|
775
|
+
:param action: (action) action info from tkinter. Contains the x and y coordinates of a mouse
|
|
776
|
+
:type action:
|
|
777
|
+
"""
|
|
778
|
+
|
|
779
|
+
if not self.MouseButtonDown and not self.motion_events:
|
|
780
|
+
return
|
|
781
|
+
self.ClickPosition = self._convert_canvas_xy_to_xy(action.x, action.y)
|
|
782
|
+
self.ParentForm.LastButtonClickedWasRealtime = self.DragSubmits
|
|
783
|
+
if self.Key is not None:
|
|
784
|
+
self.ParentForm.LastButtonClicked = self.Key
|
|
785
|
+
else:
|
|
786
|
+
self.ParentForm.LastButtonClicked = '__GRAPH__' # need to put something rather than None
|
|
787
|
+
if self.motion_events and not self.MouseButtonDown:
|
|
788
|
+
if isinstance(self.ParentForm.LastButtonClicked, str):
|
|
789
|
+
self.ParentForm.LastButtonClicked = self.ParentForm.LastButtonClicked + '+MOVE'
|
|
790
|
+
else:
|
|
791
|
+
self.ParentForm.LastButtonClicked = (self.ParentForm.LastButtonClicked, '+MOVE')
|
|
792
|
+
_exit_mainloop(self.ParentForm)
|
|
793
|
+
|
|
794
|
+
BringFigureToFront = bring_figure_to_front
|
|
795
|
+
ButtonPressCallBack = button_press_call_back
|
|
796
|
+
ButtonReleaseCallBack = button_release_call_back
|
|
797
|
+
DeleteFigure = delete_figure
|
|
798
|
+
DrawArc = draw_arc
|
|
799
|
+
DrawCircle = draw_circle
|
|
800
|
+
DrawImage = draw_image
|
|
801
|
+
DrawLine = draw_line
|
|
802
|
+
DrawOval = draw_oval
|
|
803
|
+
DrawPoint = draw_point
|
|
804
|
+
DrawPolygon = draw_polygon
|
|
805
|
+
DrawLines = draw_lines
|
|
806
|
+
DrawRectangle = draw_rectangle
|
|
807
|
+
DrawText = draw_text
|
|
808
|
+
GetFiguresAtLocation = get_figures_at_location
|
|
809
|
+
GetBoundingBox = get_bounding_box
|
|
810
|
+
Erase = erase
|
|
811
|
+
MotionCallBack = motion_call_back
|
|
812
|
+
Move = move
|
|
813
|
+
MoveFigure = move_figure
|
|
814
|
+
RelocateFigure = relocate_figure
|
|
815
|
+
SendFigureToBack = send_figure_to_back
|
|
816
|
+
TKCanvas = tk_canvas
|
|
817
|
+
Change = badlo
|