tksheet 7.4.2__py3-none-any.whl → 7.4.4__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.
- tksheet/__init__.py +2 -1
- tksheet/column_headers.py +21 -14
- tksheet/functions.py +87 -77
- tksheet/main_table.py +98 -86
- tksheet/row_index.py +42 -32
- tksheet/sheet.py +51 -70
- tksheet/sheet_options.py +3 -1
- tksheet/sorting.py +273 -77
- {tksheet-7.4.2.dist-info → tksheet-7.4.4.dist-info}/METADATA +3 -1
- tksheet-7.4.4.dist-info/RECORD +22 -0
- tksheet-7.4.2.dist-info/RECORD +0 -22
- {tksheet-7.4.2.dist-info → tksheet-7.4.4.dist-info}/LICENSE.txt +0 -0
- {tksheet-7.4.2.dist-info → tksheet-7.4.4.dist-info}/WHEEL +0 -0
- {tksheet-7.4.2.dist-info → tksheet-7.4.4.dist-info}/top_level.txt +0 -0
tksheet/sheet.py
CHANGED
@@ -54,6 +54,7 @@ from .functions import (
|
|
54
54
|
)
|
55
55
|
from .main_table import MainTable
|
56
56
|
from .other_classes import (
|
57
|
+
Box_nt,
|
57
58
|
DotDict,
|
58
59
|
EventDataDict,
|
59
60
|
FontTuple,
|
@@ -66,6 +67,7 @@ from .other_classes import (
|
|
66
67
|
)
|
67
68
|
from .row_index import RowIndex
|
68
69
|
from .sheet_options import new_sheet_options
|
70
|
+
from .sorting import fast_sort_key, natural_sort_key, version_sort_key # noqa: F401
|
69
71
|
from .themes import (
|
70
72
|
theme_black,
|
71
73
|
theme_dark,
|
@@ -84,7 +86,7 @@ class Sheet(tk.Frame):
|
|
84
86
|
parent: tk.Misc,
|
85
87
|
name: str = "!sheet",
|
86
88
|
show_table: bool = True,
|
87
|
-
show_top_left: bool =
|
89
|
+
show_top_left: bool | None = None,
|
88
90
|
show_row_index: bool = True,
|
89
91
|
show_header: bool = True,
|
90
92
|
show_x_scrollbar: bool = True,
|
@@ -187,6 +189,7 @@ class Sheet(tk.Frame):
|
|
187
189
|
table_wrap: Literal["", "w", "c"] = "c",
|
188
190
|
index_wrap: Literal["", "w", "c"] = "c",
|
189
191
|
header_wrap: Literal["", "w", "c"] = "c",
|
192
|
+
sort_key: Callable = natural_sort_key,
|
190
193
|
# colors
|
191
194
|
outline_thickness: int = 0,
|
192
195
|
theme: str = "light blue",
|
@@ -429,14 +432,18 @@ class Sheet(tk.Frame):
|
|
429
432
|
orient="vertical",
|
430
433
|
style=f"Sheet{self.unique_id}.Vertical.TScrollbar",
|
431
434
|
)
|
435
|
+
self.MT["yscrollcommand"] = self.yscroll.set
|
436
|
+
self.RI["yscrollcommand"] = self.yscroll.set
|
432
437
|
self.xscroll = ttk.Scrollbar(
|
433
438
|
self,
|
434
439
|
command=self.MT._xscrollbar,
|
435
440
|
orient="horizontal",
|
436
441
|
style=f"Sheet{self.unique_id}.Horizontal.TScrollbar",
|
437
442
|
)
|
443
|
+
self.MT["xscrollcommand"] = self.xscroll.set
|
444
|
+
self.CH["xscrollcommand"] = self.xscroll.set
|
438
445
|
self.show()
|
439
|
-
if
|
446
|
+
if show_top_left is False or (show_top_left is None and (not show_row_index or not show_header)):
|
440
447
|
self.hide("top_left")
|
441
448
|
if not show_row_index:
|
442
449
|
self.hide("row_index")
|
@@ -728,9 +735,9 @@ class Sheet(tk.Frame):
|
|
728
735
|
- "begin_rc_delete_column", "begin_delete_columns"
|
729
736
|
- "rc_delete_column", "end_rc_delete_column","end_delete_columns", "delete_columns"
|
730
737
|
- "begin_rc_insert_column", "begin_insert_column", "begin_insert_columns", "begin_add_column","begin_rc_add_column", "begin_add_columns"
|
731
|
-
- "rc_insert_column", "end_rc_insert_column", "end_insert_column", "end_insert_columns", "rc_add_column", "end_rc_add_column", "end_add_column", "end_add_columns"
|
738
|
+
- "rc_insert_column", "end_rc_insert_column", "end_insert_column", "end_insert_columns", "rc_add_column", "end_rc_add_column", "end_add_column", "end_add_columns", "add_columns"
|
732
739
|
- "begin_rc_insert_row", "begin_insert_row", "begin_insert_rows", "begin_rc_add_row", "begin_add_row", "begin_add_rows"
|
733
|
-
- "rc_insert_row", "end_rc_insert_row", "end_insert_row", "end_insert_rows", "rc_add_row", "end_rc_add_row", "end_add_row", "end_add_rows"
|
740
|
+
- "rc_insert_row", "end_rc_insert_row", "end_insert_row", "end_insert_rows", "rc_add_row", "end_rc_add_row", "end_add_row", "end_add_rows", "add_rows"
|
734
741
|
- "row_height_resize"
|
735
742
|
- "column_width_resize"
|
736
743
|
- "cell_select"
|
@@ -1031,6 +1038,7 @@ class Sheet(tk.Frame):
|
|
1031
1038
|
"end_rc_add_column",
|
1032
1039
|
"end_add_column",
|
1033
1040
|
"end_add_columns",
|
1041
|
+
"add_columns",
|
1034
1042
|
):
|
1035
1043
|
self.MT.extra_end_insert_cols_rc_func = f
|
1036
1044
|
|
@@ -1052,6 +1060,7 @@ class Sheet(tk.Frame):
|
|
1052
1060
|
"end_rc_add_row",
|
1053
1061
|
"end_add_row",
|
1054
1062
|
"end_add_rows",
|
1063
|
+
"add_rows",
|
1055
1064
|
):
|
1056
1065
|
self.MT.extra_end_insert_rows_rc_func = f
|
1057
1066
|
|
@@ -2328,7 +2337,6 @@ class Sheet(tk.Frame):
|
|
2328
2337
|
data_indexes=data_indexes,
|
2329
2338
|
undo=undo,
|
2330
2339
|
emit_event=emit_event,
|
2331
|
-
ext=True,
|
2332
2340
|
)
|
2333
2341
|
self.set_refresh_timer(redraw)
|
2334
2342
|
return event_data
|
@@ -2350,7 +2358,6 @@ class Sheet(tk.Frame):
|
|
2350
2358
|
data_indexes=data_indexes,
|
2351
2359
|
undo=undo,
|
2352
2360
|
emit_event=emit_event,
|
2353
|
-
ext=True,
|
2354
2361
|
)
|
2355
2362
|
self.set_refresh_timer(redraw)
|
2356
2363
|
return event_data
|
@@ -2582,7 +2589,7 @@ class Sheet(tk.Frame):
|
|
2582
2589
|
|
2583
2590
|
def sort(
|
2584
2591
|
self,
|
2585
|
-
|
2592
|
+
*box: CreateSpanTypes,
|
2586
2593
|
reverse: bool = False,
|
2587
2594
|
row_wise: bool = False,
|
2588
2595
|
validation: bool = True,
|
@@ -2595,17 +2602,11 @@ class Sheet(tk.Frame):
|
|
2595
2602
|
This method sorts the data within one or multiple box regions defined by their coordinates. Each box's columns are sorted independently.
|
2596
2603
|
|
2597
2604
|
Args:
|
2598
|
-
boxes (
|
2599
|
-
- From Row (inclusive)
|
2600
|
-
- From Column (inclusive)
|
2601
|
-
- Up To Row (exclusive)
|
2602
|
-
- Up To Column (exclusive)
|
2603
|
-
If None, it will sort the currently selected boxes or the entire table.
|
2604
|
-
If Span, it will use the span coordinates.
|
2605
|
+
boxes (CreateSpanTypes): A type that can create a Span.
|
2605
2606
|
|
2606
2607
|
reverse (bool): If True, sorts in descending order. Default is False (ascending).
|
2607
2608
|
|
2608
|
-
row_wise (bool): if True sorts cells row-wise. Default is column-wise
|
2609
|
+
row_wise (bool): if True sorts cells row-wise. Default is column-wise.
|
2609
2610
|
|
2610
2611
|
validation (bool): If True, checks if the new cell values are valid according to any restrictions
|
2611
2612
|
(e.g., dropdown validations) before applying the sort. Default is True.
|
@@ -2622,19 +2623,21 @@ class Sheet(tk.Frame):
|
|
2622
2623
|
ValueError: If the input boxes are not in the expected format or if the data cannot be sorted.
|
2623
2624
|
|
2624
2625
|
Note:
|
2625
|
-
- Sorting is performed column-wise within each box.
|
2626
2626
|
- If validation is enabled, any cell content that fails validation will not be updated.
|
2627
2627
|
- Any cell options attached to cells will not be moved. Event data can be used to re-locate them.
|
2628
2628
|
"""
|
2629
|
-
if isinstance(boxes, Span):
|
2630
|
-
boxes = [boxes.coords]
|
2631
2629
|
return self.MT.sort_boxes(
|
2632
|
-
boxes=
|
2630
|
+
boxes={Box_nt(*self.span_from_key(*box).coords): "cells"},
|
2631
|
+
reverse=reverse,
|
2632
|
+
row_wise=row_wise,
|
2633
|
+
validation=validation,
|
2634
|
+
key=key,
|
2635
|
+
undo=undo,
|
2633
2636
|
)
|
2634
2637
|
|
2635
2638
|
def sort_rows(
|
2636
2639
|
self,
|
2637
|
-
rows: AnyIter[int] | Span | None = None,
|
2640
|
+
rows: AnyIter[int] | Span | int | None = None,
|
2638
2641
|
reverse: bool = False,
|
2639
2642
|
validation: bool = True,
|
2640
2643
|
key: Callable | None = None,
|
@@ -2642,11 +2645,13 @@ class Sheet(tk.Frame):
|
|
2642
2645
|
) -> EventDataDict:
|
2643
2646
|
if isinstance(rows, Span):
|
2644
2647
|
rows = rows.rows
|
2648
|
+
elif isinstance(rows, int):
|
2649
|
+
rows = (rows,)
|
2645
2650
|
return self.RI._sort_rows(rows=rows, reverse=reverse, validation=validation, key=key, undo=undo)
|
2646
2651
|
|
2647
2652
|
def sort_columns(
|
2648
2653
|
self,
|
2649
|
-
columns: AnyIter[int] | Span | None = None,
|
2654
|
+
columns: AnyIter[int] | Span | int | None = None,
|
2650
2655
|
reverse: bool = False,
|
2651
2656
|
validation: bool = True,
|
2652
2657
|
key: Callable | None = None,
|
@@ -2654,6 +2659,8 @@ class Sheet(tk.Frame):
|
|
2654
2659
|
) -> EventDataDict:
|
2655
2660
|
if isinstance(columns, Span):
|
2656
2661
|
columns = columns.columns
|
2662
|
+
elif isinstance(columns, int):
|
2663
|
+
columns = (columns,)
|
2657
2664
|
return self.CH._sort_columns(columns=columns, reverse=reverse, validation=validation, key=key, undo=undo)
|
2658
2665
|
|
2659
2666
|
def sort_rows_by_column(
|
@@ -4365,19 +4372,13 @@ class Sheet(tk.Frame):
|
|
4365
4372
|
self.MT.grid(row=1, column=1, sticky="nswe")
|
4366
4373
|
if canvas in ("all", "row_index", "index"):
|
4367
4374
|
self.RI.grid(row=1, column=0, sticky="nswe")
|
4368
|
-
self.MT["yscrollcommand"] = self.yscroll.set
|
4369
|
-
self.RI["yscrollcommand"] = self.yscroll.set
|
4370
4375
|
self.MT.show_index = True
|
4371
|
-
if self.MT.show_header:
|
4372
|
-
self.show("top_left")
|
4373
4376
|
if canvas in ("all", "header"):
|
4374
4377
|
self.CH.grid(row=0, column=1, sticky="nswe")
|
4375
|
-
self.MT["xscrollcommand"] = self.xscroll.set
|
4376
|
-
self.CH["xscrollcommand"] = self.xscroll.set
|
4377
4378
|
self.MT.show_header = True
|
4378
|
-
|
4379
|
-
|
4380
|
-
|
4379
|
+
if canvas in ("all", "top_left") or (
|
4380
|
+
self.ops.show_top_left is not False and self.MT.show_header and self.MT.show_index
|
4381
|
+
):
|
4381
4382
|
self.TL.grid(row=0, column=0)
|
4382
4383
|
if canvas in ("all", "x_scrollbar"):
|
4383
4384
|
self.xscroll.grid(row=2, column=0, columnspan=2, sticky="nswe")
|
@@ -4405,17 +4406,13 @@ class Sheet(tk.Frame):
|
|
4405
4406
|
) -> Sheet:
|
4406
4407
|
if canvas in ("all", "row_index"):
|
4407
4408
|
self.RI.grid_remove()
|
4408
|
-
self.RI["yscrollcommand"] = 0
|
4409
4409
|
self.MT.show_index = False
|
4410
|
-
if not self.ops.show_top_left:
|
4411
|
-
self.hide("top_left")
|
4412
4410
|
if canvas in ("all", "header"):
|
4413
4411
|
self.CH.grid_remove()
|
4414
|
-
self.CH["xscrollcommand"] = 0
|
4415
4412
|
self.MT.show_header = False
|
4416
|
-
|
4417
|
-
|
4418
|
-
|
4413
|
+
if canvas in ("all", "top_left") or (
|
4414
|
+
not self.ops.show_top_left and (not self.MT.show_index or not self.MT.show_header)
|
4415
|
+
):
|
4419
4416
|
self.TL.grid_remove()
|
4420
4417
|
if canvas in ("all", "x_scrollbar"):
|
4421
4418
|
self.xscroll.grid_remove()
|
@@ -4668,24 +4665,14 @@ class Sheet(tk.Frame):
|
|
4668
4665
|
Also retrieves any row or column options
|
4669
4666
|
impacting that cell
|
4670
4667
|
"""
|
4671
|
-
|
4672
|
-
|
4673
|
-
|
4674
|
-
|
4675
|
-
|
4676
|
-
|
4677
|
-
|
4678
|
-
|
4679
|
-
row=rowops,
|
4680
|
-
column=columnops,
|
4681
|
-
)
|
4682
|
-
if cellops and (row, column) in self.MT.cell_options:
|
4683
|
-
return self.MT.cell_options[(row, column)]
|
4684
|
-
if rowops and row in self.MT.row_options:
|
4685
|
-
return self.MT.row_options[row]
|
4686
|
-
if columnops and column in self.MT.col_options:
|
4687
|
-
return self.MT.col_options[column]
|
4688
|
-
return {}
|
4668
|
+
return self.MT.get_cell_kwargs(
|
4669
|
+
datarn=row,
|
4670
|
+
datacn=alpha2idx(column) if isinstance(column, str) else column,
|
4671
|
+
key=key,
|
4672
|
+
cell=cellops,
|
4673
|
+
row=rowops,
|
4674
|
+
column=columnops,
|
4675
|
+
)
|
4689
4676
|
|
4690
4677
|
def index_props(
|
4691
4678
|
self,
|
@@ -4696,12 +4683,10 @@ class Sheet(tk.Frame):
|
|
4696
4683
|
Retrieve options (properties - props)
|
4697
4684
|
from a cell in the index
|
4698
4685
|
"""
|
4699
|
-
|
4700
|
-
|
4701
|
-
|
4702
|
-
|
4703
|
-
)
|
4704
|
-
return self.RI.cell_options[row] if row in self.RI.cell_options else {}
|
4686
|
+
return self.RI.get_cell_kwargs(
|
4687
|
+
datarn=row,
|
4688
|
+
key=key,
|
4689
|
+
)
|
4705
4690
|
|
4706
4691
|
def header_props(
|
4707
4692
|
self,
|
@@ -4712,14 +4697,10 @@ class Sheet(tk.Frame):
|
|
4712
4697
|
Retrieve options (properties - props)
|
4713
4698
|
from a cell in the header
|
4714
4699
|
"""
|
4715
|
-
|
4716
|
-
column
|
4717
|
-
|
4718
|
-
|
4719
|
-
datacn=column,
|
4720
|
-
key=key,
|
4721
|
-
)
|
4722
|
-
return self.CH.cell_options[column] if column in self.CH.cell_options else {}
|
4700
|
+
return self.CH.get_cell_kwargs(
|
4701
|
+
datacn=alpha2idx(column) if isinstance(column, str) else column,
|
4702
|
+
key=key,
|
4703
|
+
)
|
4723
4704
|
|
4724
4705
|
def get_cell_options(
|
4725
4706
|
self,
|
@@ -7241,7 +7222,7 @@ class Dropdown(Sheet):
|
|
7241
7222
|
|
7242
7223
|
def search_and_see(self, event: object = None) -> str:
|
7243
7224
|
if self.search_function is not None:
|
7244
|
-
rn = self.search_function(search_for=rf"{event['value']}"
|
7225
|
+
rn = self.search_function(search_for=rf"{event['value']}", data=(r[0] for r in self.MT.data))
|
7245
7226
|
if isinstance(rn, int):
|
7246
7227
|
self.row = rn
|
7247
7228
|
self.see(self.row, 0, redraw=False)
|
tksheet/sheet_options.py
CHANGED
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
from .constants import USER_OS, ctrl_key
|
4
4
|
from .other_classes import DotDict, FontTuple
|
5
|
+
from .sorting import fast_sort_key, natural_sort_key, version_sort_key # noqa: F401
|
5
6
|
from .themes import theme_light_blue
|
6
7
|
|
7
8
|
|
@@ -254,6 +255,7 @@ def new_sheet_options() -> DotDict:
|
|
254
255
|
"max_header_height": float("inf"),
|
255
256
|
"max_row_height": float("inf"),
|
256
257
|
"max_index_width": float("inf"),
|
257
|
-
"show_top_left":
|
258
|
+
"show_top_left": None,
|
259
|
+
"sort_key": natural_sort_key,
|
258
260
|
}
|
259
261
|
)
|