generated from xinetzone/sphinx-demo
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
liuxinwei
committed
Oct 15, 2024
1 parent
3be9763
commit 98e01e6
Showing
10 changed files
with
569 additions
and
214 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
"""Dive into Python.""" | ||
__version__ = '0.6.1' | ||
__version__ = '0.6.2' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,260 @@ | ||
'''Some of the actions related to the graph. | ||
''' | ||
from tkinter import Canvas as _Canvas, StringVar, ttk | ||
|
||
|
||
class Canvas(_Canvas): | ||
'''Graphic elements are composed of line(segment), rectangle, ellipse, and arc. | ||
''' | ||
|
||
def __init__(self, master=None, cnf={}, **kw): | ||
'''The base class of all graphics frames. | ||
:param master: a widget of tkinter or tkinter.ttk. | ||
''' | ||
super().__init__(master, cnf, **kw) | ||
|
||
def draw_graph(self, graph_type, direction, color='blue', width=1, tags=None, **kwargs): | ||
'''Draw basic graphic elements. | ||
:param direction: Specifies the orientation of the graphic element. | ||
Union[int, float] -> (x_0,y_0,x_,y_1), (x_0, y_0) refers to the starting point of | ||
the reference brush (i.e., the left mouse button is pressed), and (x_1, y_1) refers to | ||
the end position of the reference brush (i.e., release the left mouse button). | ||
Multipoint sequences are supported for 'line' and 'polygon', | ||
for example ((x_0, y_0), (x_1, y_1), (x_2, y_2)). | ||
:param graph_type: Types of graphic elements. | ||
(str) 'rectangle', 'oval', 'line', 'arc'(That is, segment), 'polygon'. | ||
Note that 'line' can no longer pass in the parameter 'fill', and | ||
the remaining graph_type cannot pass in the parameter 'outline'. | ||
:param color: The color of the graphic element. | ||
:param width: The width of the graphic element.(That is, center fill) | ||
:param tags: The tags of the graphic element. | ||
It cannot be a pure number (such as 1 or '1' or '1 2 3'), it can be a list, a tuple, | ||
or a string separated by a space(is converted to String tupers separated by a blank space). | ||
The collection or dictionary is converted to a string. | ||
Example: | ||
['line', 'graph'], ('test', 'g'), 'line', | ||
' line kind '(The blanks at both ends are automatically removed), and so on. | ||
:param style: Style of the arc in {'arc', 'chord', or 'pieslice'}. | ||
:return: Unique identifier solely for graphic elements. | ||
''' | ||
if tags is None: | ||
if graph_type in ('rectangle', 'oval', 'line', 'arc'): | ||
tags = f"graph {graph_type}" | ||
else: | ||
tags = 'graph' | ||
|
||
com_kw = {'width': width, 'tags': tags} | ||
kw = {**com_kw, 'outline': color} | ||
line_kw = {**com_kw, 'fill': color} | ||
if graph_type == 'line': | ||
kwargs.update(line_kw) | ||
else: | ||
kwargs.update(kw) | ||
func = eval(f"self.create_{graph_type}") | ||
graph_id = func(*direction, **kwargs) | ||
return graph_id | ||
|
||
class Drawing(Canvas): | ||
'''Create graphic elements (graph) including rectangular boxes (which can be square points), | ||
ovals (circular points), and segments. | ||
Press the left mouse button to start painting, release the left | ||
mouse button for the end of the painting. | ||
''' | ||
|
||
def __init__(self, master=None, selector=None, cnf={}, **kw): | ||
'''Click the left mouse button to start painting, release | ||
the left mouse button to complete the painting. | ||
:param selector: The graphics selector, which is an instance of Selector. | ||
''' | ||
super().__init__(master, cnf, **kw) | ||
self.selector = selector | ||
|
||
self._init_params() | ||
self._draw_bind() | ||
|
||
def _draw_bind(self): | ||
self.bind("<1>", self.update_xy) | ||
self.bind("<ButtonRelease-1>", self.draw) | ||
|
||
def _init_params(self): | ||
self.x = self.y = 0 | ||
|
||
def update_xy(self, event): | ||
'''Press the left mouse button to record the coordinates of the left mouse button''' | ||
self.x = self.canvasx(event.x) | ||
self.y = self.canvasy(event.y) | ||
|
||
def get_bbox(self, event): | ||
x0, y0 = self.x, self.y # The upper-left coordinates of the graph | ||
self.update_xy(event) | ||
x1, y1 = self.x, self.y # Lower-right coordinates of the graph | ||
bbox = x0, y0, x1, y1 | ||
return bbox | ||
|
||
def draw(self, event): | ||
'''Release the left mouse button to finish painting.''' | ||
self.configure(cursor="arrow") | ||
bbox = self.get_bbox(event) | ||
self.create_graph(bbox) | ||
|
||
def create_graph(self, bbox): | ||
'''Create a graphic. | ||
:param bbox: (x0,y0,x1,y1) | ||
''' | ||
x0, y0, x1, y1 = bbox | ||
cond1 = x0 == x1 and y0 == y1 and 'point' not in self.selector.graph_type | ||
cond2 = 'point' in self.selector.graph_type and (x0 != x1 or y0 != y1) | ||
if cond1 or cond2: | ||
return | ||
else: | ||
self.draw_graph(self.selector.graph_type.split('_') | ||
[0], bbox, self.selector.color) | ||
|
||
class TrajectoryDrawing(Drawing): | ||
'''Draw based on the mouse's trajectory. | ||
Click the left mouse button to start painting, move the | ||
left mouse button 'after_time' after the completion of painting. | ||
''' | ||
|
||
def __init__(self, master, selector, after_time=1000, cnf={}, **kw): | ||
super().__init__(master, selector, cnf, **kw) | ||
self.after_time = after_time | ||
self.bind("<1>", self.update_xy) | ||
self.bind("<ButtonRelease-1>", self.update_xy) | ||
self.bind("<Button1-Motion>", self.draw) | ||
|
||
def draw(self, event): | ||
'''Release the left mouse button to finish painting.''' | ||
self.configure(cursor="arrow") | ||
self.after(self.after_time) | ||
bbox = self.get_bbox(event) | ||
self.create_graph(bbox) | ||
|
||
class Graph(Drawing): | ||
'''Graph is a drawing tool for manipulating graphic objects. | ||
''' | ||
def __init__(self, master, selector, cnf={}, **kw): | ||
super().__init__(master, selector, cnf, **kw) | ||
self.selected_tags = None | ||
self.edit_var = StringVar() | ||
|
||
@property | ||
def tags_dict(self): | ||
return { | ||
'Single element': 'current', | ||
'All elements': 'all', | ||
'All graphic elements': 'graph', | ||
'⬜': 'rectangle', | ||
'⚪': 'oval', | ||
'⸺': 'line', | ||
'⯀': 'rectangle_point', | ||
'●': 'oval_point' | ||
} | ||
|
||
def move_strides(self, event): | ||
x, y = self.x, self.y | ||
self.update_xy(event) | ||
x_move = self.x - x | ||
y_move = self.y - y | ||
return x_move, y_move | ||
|
||
def move_graph(self, event): | ||
x_move, y_move = self.move_strides(event) | ||
self.move(self.selected_tags, x_move, y_move) | ||
|
||
def delete_graph(self, event): | ||
self.delete(self.selected_tags) | ||
|
||
def select_graph(self, event, edit_option): | ||
self.configure(cursor="target") | ||
self.update_xy(event) | ||
tags = self.tags_dict[edit_option] | ||
if tags == 'current': | ||
self.selected_tags = self.find_withtag(tags) | ||
else: | ||
self.selected_tags = tags | ||
|
||
def bind_graph(self): | ||
self.unbind('<ButtonRelease-1>') | ||
self.unbind('<1>') | ||
edit = self.edit_var.get() | ||
if edit == 'drawing': | ||
self._draw_bind() # reset bind | ||
elif 'move' in edit: | ||
self.bind('<1>', lambda event: self.select_graph( | ||
event, edit.split('/')[1])) | ||
self.bind('<ButtonRelease-1>', self.move_graph) | ||
elif 'delete' in edit: | ||
self.bind('<1>', lambda event: self.select_graph( | ||
event, edit.split('/')[1])) | ||
self.bind('<ButtonRelease-1>', self.delete_graph) | ||
|
||
class GraphScrollable(Graph): | ||
'''Pin the picture and label it on it. | ||
''' | ||
|
||
def __init__(self, master, selector, cnf={}, **kw): | ||
super().__init__(master, selector, cnf, **kw) | ||
self.coord_var = StringVar() | ||
self.coord_label = ttk.Label(self, textvariable=self.coord_var) | ||
self._set_scroll() | ||
self._scroll_command() | ||
self.configure(xscrollcommand=self.scroll_x.set, | ||
yscrollcommand=self.scroll_y.set) | ||
self.bind("<3>", self.mouse_motion) | ||
self.bind("<Configure>", self.resize) | ||
self.update_idletasks() | ||
#self.minsize(self.winfo_width(), self.winfo_height()) | ||
self.scroll_x.pack(side='top', fill='x') | ||
self.pack(side='left', expand='yes', fill='both') | ||
self.scroll_y.pack(side='right', fill='y') | ||
self.coord_label.pack(side='bottom', fill='x') | ||
|
||
def draw(self, event): | ||
'''Release the left mouse button to finish painting.''' | ||
self.configure(cursor="arrow") | ||
bbox = self.get_bbox(event) | ||
self.create_graph(bbox) | ||
self.coord_var.set(f'coordinate: {bbox[:2]} to {bbox[2:]}') | ||
|
||
def select_graph(self, event, edit_option): | ||
self.configure(cursor="target") | ||
self.update_xy(event) | ||
tags = self.tags_dict[edit_option] | ||
image_tags = self.find_withtag('image') | ||
selected_tags = self.find_withtag(tags) | ||
self.selected_tags = set(selected_tags) - set(image_tags) | ||
|
||
def move_graph(self, event): | ||
x_move, y_move = self.move_strides(event) | ||
for tag in self.selected_tags: | ||
self.move(tag, x_move, y_move) | ||
|
||
def delete_graph(self, event): | ||
for tag in self.selected_tags: | ||
self.delete(tag) | ||
|
||
def _set_scroll(self): | ||
self.scroll_x = ttk.Scrollbar(self, orient='horizontal') | ||
self.scroll_y = ttk.Scrollbar(self, orient='vertical') | ||
|
||
def mouse_motion(self, event): | ||
x = event.x | ||
y = event.y | ||
text = f"coordinate: ({x}, {y})|| {self.canvasx(x), self.canvasy(y)}" | ||
self.coord_var.set(text) | ||
|
||
def _scroll_command(self): | ||
self.scroll_x['command'] = self.xview | ||
self.scroll_y['command'] = self.yview | ||
|
||
def resize(self, event): | ||
region = self.bbox('all') | ||
self.configure(scrollregion=region) | ||
|
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.