Skip to content

Commit

Permalink
Added new Tableview widget and tableview module (#110)
Browse files Browse the repository at this point in the history
  • Loading branch information
israel-dryer committed Jan 3, 2022
1 parent 2abfeb4 commit 3bbb6d0
Show file tree
Hide file tree
Showing 17 changed files with 3,954 additions and 26 deletions.
1,000 changes: 1,000 additions & 0 deletions development/new_widgets/Sample1000.csv

Large diffs are not rendered by default.

638 changes: 638 additions & 0 deletions development/new_widgets/datatable.py

Large diffs are not rendered by default.

Empty file.
40 changes: 40 additions & 0 deletions development/tests/tableview.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import ttkbootstrap as ttk
from ttkbootstrap.constants import *
from pathlib import Path
import csv
from ttkbootstrap.tableview import Tableview
from ttkbootstrap.utility import scale_size

app = ttk.Window(themename='sandstone')
colors = app.style.colors

p = Path(".") / "development/new_widgets/Sample1000.csv"
with open(p, encoding="utf-8") as f:
reader = csv.reader(f)
next(reader)
rowdata = list(reader)


# column configuration options
# text, image, command, anchor, width, minwidth, maxwidth, stretch
coldata = [
{"text": "SerialNumber", "stretch": False},
"CompanyName",
"Employee",
"Description",
{"text": "Leave", "stretch": False},
]

dt = Tableview(
master=app,
coldata=coldata,
rowdata=rowdata,
paginated=True,
searchable=True,
bootstyle=DARK,
stripecolor=('#eee', None),
autofit=False
)
dt.pack(fill=BOTH, expand=YES, padx=5, pady=5)

app.mainloop()
22 changes: 13 additions & 9 deletions development/tests/widget_styles/test_entry.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import tkinter as tk
import ttkbootstrap as ttk
from ttkbootstrap.constants import *
from random import choice
from ttkbootstrap import utility
utility.enable_high_dpi_awareness()

DARK = 'superhero'
LIGHT = 'flatly'
Expand All @@ -27,28 +26,33 @@ def create_entry_test(bootstyle, style):
entry.pack(padx=5, pady=5, fill=tk.BOTH)
entry.insert(tk.END, color)

# readonly
entry = ttk.Entry(frame, bootstyle=bootstyle)
entry.insert(tk.END, 'readonly')
entry.configure(state=READONLY)
entry.pack(padx=5, pady=5, fill=tk.BOTH)

# disabled
entry = ttk.Entry(frame, bootstyle=bootstyle)
entry.insert(tk.END, bootstyle)
entry.configure(state=tk.DISABLED)
entry.insert(tk.END, 'disabled')
entry.configure(state=DISABLED)
entry.pack(padx=5, pady=5, fill=tk.BOTH)

return frame


def change_style():
theme = choice(style.theme_names())
style.theme_use(theme)
theme = choice(root.style.theme_names())
root.style.theme_use(theme)


if __name__ == '__main__':
# create visual widget style tests
root = tk.Tk()
style = ttk.Style()
root = ttk.Window(themename='sandstone')

ttk.Button(text="Change Theme", command=change_style).pack(padx=10, pady=10)

test1 = create_entry_test('TEntry', style)
test1 = create_entry_test('TEntry', root.style)
test1.pack(side=tk.LEFT, fill=tk.BOTH)

root.mainloop()
8 changes: 6 additions & 2 deletions docs/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ This module contains classes that provide emojis or image icons for your
application. They can be used in text as `Emoji` or in the
`PhotoImage` class as `Icon`.

[Emoji](icons/icons/emoji.md)
[Emoji](icons/emoji.md)
[Icon](icons/icon.md)

## 📜 scrolled module
Expand All @@ -32,7 +32,6 @@ This module contains various scrolled widgets such as `ScrolledText` and
[ScrolledFrame](scrolled/scrolledframe.md)
[ScrolledText](scrolled/scrolledtext.md)


## 🎨 style module
This module contains the classes that make up the ttkbootstrap theme and
style engine. Depending on how you use ttkbootstrap, you may never need
Expand All @@ -46,6 +45,11 @@ docs are here for your reference.
[StyleBuilderTTK](style/stylebuilderttk.md)
[Bootstyle](style/bootstyle.md)

## 🪟 [tableview module](tableview/tableview.md)
[Tableview](tableview/tableview.md)
[TableColumn](tableview/tablecolumn.md)
[TableRow](tableview/tablerow.md)

## 🛎️ [toast module](toast.md)
This module has a class called `ToastNotification` which provides a
semi-transparent popup window for temporary alerts or messages.
Expand Down
8 changes: 8 additions & 0 deletions docs/api/tableview/tablecolumn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# TableColumn

::: ttkbootstrap.tableview.TableColumn
selection:
filters: ["!^_", "^__init__"]
rendering:
heading_level: 2
show_root_heading: true
9 changes: 9 additions & 0 deletions docs/api/tableview/tablerow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# TableRow

::: ttkbootstrap.tableview.TableRow
selection:
filters: ["!^_", "^__init__"]
rendering:
heading_level: 2
show_root_heading: true

8 changes: 8 additions & 0 deletions docs/api/tableview/tableview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Tableview

::: ttkbootstrap.tableview.Tableview
selection:
filters: ["!^_", "^__init__"]
rendering:
heading_level: 2
show_root_heading: true
Binary file added docs/assets/widgets/tableview-1.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/widgets/tableview-2.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/widgets/tableview.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ nav:
- api/style/stylebuildertk.md
- api/style/stylebuilderttk.md
- api/style/themedefinition.md
- 'tableview module':
- api/tableview/tableview.md
- api/tableview/tablecolumn.md
- api/tableview/tablerow.md
- 'toast module': api/toast.md
- 'tooltip module': api/tooltip.md
- 'utility module': api/utility.md
Expand Down
130 changes: 115 additions & 15 deletions src/ttkbootstrap/style.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ def colors(self):
def configure(self, style, query_opt: Any = None, **kw):
if query_opt:
return super().configure(style, query_opt=query_opt, **kw)

if not self.style_exists_in_theme(style):
ttkstyle = Bootstyle.update_ttk_widget_style(None, style)
else:
Expand Down Expand Up @@ -613,7 +613,7 @@ def _get_builder_tk():

def _build_configure(self, style, **kw):
"""Calls configure of superclass; used by style builder classes."""
super().configure(style, **kw)
super().configure(style, **kw)

def _load_themes(self):
"""Load all ttkbootstrap defined themes"""
Expand Down Expand Up @@ -1109,6 +1109,9 @@ def create_default_style(self):
borderwidth=1,
focuscolor="",
)
# this is general style applied to the tableview
self.create_link_button_style()
self.style.configure("symbol.Link.TButton", font="-size 16")

def create_combobox_style(self, colorname=DEFAULT):
"""Create a style for the ttk.Combobox widget.
Expand Down Expand Up @@ -1232,8 +1235,8 @@ def create_separator_style(self, colorname=DEFAULT):
HSTYLE = "Horizontal.TSeparator"
VSTYLE = "Vertical.TSeparator"

hsize = self.scale_size([40, 1])
vsize = self.scale_size([1, 40])
hsize = [40, 1]
vsize = [1, 40]

# style colors
if self.is_light_theme:
Expand All @@ -1252,9 +1255,7 @@ def create_separator_style(self, colorname=DEFAULT):

# horizontal separator
h_element = h_ttkstyle.replace(".TS", ".S")
h_img = ImageTk.PhotoImage(
Image.new("RGB", self.scale_size(hsize), background)
)
h_img = ImageTk.PhotoImage(Image.new("RGB", hsize, background))
h_name = util.get_image_name(h_img)
self.theme_images[h_name] = h_img

Expand All @@ -1265,9 +1266,7 @@ def create_separator_style(self, colorname=DEFAULT):

# vertical separator
v_element = v_ttkstyle.replace(".TS", ".S")
v_img = ImageTk.PhotoImage(
Image.new("RGB", self.scale_size(vsize), background)
)
v_img = ImageTk.PhotoImage(Image.new("RGB", vsize, background))
v_name = util.get_image_name(v_img)
self.theme_images[v_name] = v_img
self.style.element_create(f"{v_element}.separator", "image", v_name)
Expand Down Expand Up @@ -2398,6 +2397,104 @@ def create_spinbox_style(self, colorname=DEFAULT):
# register ttkstyles
self.style._register_ttkstyle(ttkstyle)

def create_table_treeview_style(self, colorname=DEFAULT):
"""Create a style for the Tableview widget.
Parameters:
colorname (str):
The color label used to style the widget.
"""
STYLE = "Table.Treeview"

f = font.nametofont("TkDefaultFont")
rowheight = f.metrics()["linespace"]

if self.is_light_theme:
disabled_fg = Colors.update_hsv(self.colors.inputbg, vd=-0.2)
bordercolor = self.colors.border
else:
disabled_fg = Colors.update_hsv(self.colors.inputbg, vd=-0.3)
bordercolor = self.colors.selectbg

if any([colorname == DEFAULT, colorname == ""]):
background = self.colors.inputbg
foreground = self.colors.inputfg
body_style = STYLE
header_style = f"{STYLE}.Heading"
elif colorname == LIGHT and self.is_light_theme:
background = self.colors.get(colorname)
foreground = self.colors.fg
body_style = f"{colorname}.{STYLE}"
header_style = f"{colorname}.{STYLE}.Heading"
else:
background = self.colors.get(colorname)
foreground = self.colors.selectfg
body_style = f"{colorname}.{STYLE}"
header_style = f"{colorname}.{STYLE}.Heading"

# treeview header
self.style._build_configure(
header_style,
background=background,
foreground=foreground,
relief=tk.FLAT,
padding=5,
)
self.style.map(
header_style,
foreground=[("disabled", disabled_fg)],
)
self.style._build_configure(
body_style,
background=self.colors.inputbg,
fieldbackground=self.colors.inputbg,
foreground=self.colors.inputfg,
bordercolor=bordercolor,
lightcolor=self.colors.inputbg,
darkcolor=self.colors.inputbg,
borderwidth=2,
padding=0,
rowheight=rowheight,
relief=tk.RAISED,
)
self.style.map(
body_style,
background=[("selected", self.colors.selectbg)],
foreground=[
("disabled", disabled_fg),
("selected", self.colors.selectfg),
],
)
self.style.layout(
body_style,
[
(
"Button.border",
{
"sticky": tk.NSEW,
"border": "1",
"children": [
(
"Treeview.padding",
{
"sticky": tk.NSEW,
"children": [
(
"Treeview.treearea",
{"sticky": tk.NSEW},
)
],
},
)
],
},
)
],
)
# register ttkstyles
self.style._register_ttkstyle(body_style)

def create_treeview_style(self, colorname=DEFAULT):
"""Create a style for the ttk.Treeview widget.
Expand Down Expand Up @@ -2692,7 +2789,7 @@ def create_link_button_style(self, colorname=DEFAULT):
hover = self.colors.info

if any([colorname == DEFAULT, colorname == ""]):
foreground = self.colors.primary
foreground = self.colors.fg
ttkstyle = STYLE
elif colorname == LIGHT:
foreground = self.colors.fg
Expand Down Expand Up @@ -4415,6 +4512,7 @@ class Keywords:
"date",
"metersubtxt",
"meter",
"table"
]
CLASSES = [
"button",
Expand Down Expand Up @@ -4715,7 +4813,9 @@ def __init__(self, *args, **kwargs):
if Style.get_instance().style_exists_in_theme(style):
self.configure(style=style)
else:
ttkstyle = Bootstyle.update_ttk_widget_style(self, style, **kwargs)
ttkstyle = Bootstyle.update_ttk_widget_style(
self, style, **kwargs
)
self.configure(style=ttkstyle)
elif bootstyle:
ttkstyle = Bootstyle.update_ttk_widget_style(
Expand Down Expand Up @@ -4918,11 +5018,11 @@ def override_tk_widget_constructor(func):
def __init__wrapper(self, *args, **kwargs):

# check for autostyle flag
if 'autostyle' in kwargs:
autostyle = kwargs.pop('autostyle')
if "autostyle" in kwargs:
autostyle = kwargs.pop("autostyle")
else:
autostyle = True

# instantiate the widget
func(self, *args, **kwargs)

Expand Down

0 comments on commit 3bbb6d0

Please sign in to comment.