Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scrolled frame and text #102

Merged
merged 8 commits into from
Dec 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 26 additions & 0 deletions development/new_widgets/scrolledframe.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from tkinter import Canvas, Scrollbar
import ttkbootstrap as ttk
from ttkbootstrap.constants import *


class ScrolledFrame(ttk.Canvas):

def __init__(self, master):
super().__init__(master)
self.frame = ttk.Frame(self, bootstyle=SUCCESS)
self.vbar = ttk.Scrollbar(self, orient=VERTICAL)
self.create_window(0, 0, anchor=NW, window=self.frame)
self.create_window(0, 0, anchor=NE, window=self.vbar)


if __name__ == '__main__':

app = ttk.Window()

sf = ScrolledFrame(app)
sf.pack(fill=BOTH, expand=YES)

for x in range(20):
ttk.Button(sf.frame, text="Push").pack()

app.mainloop()
132 changes: 63 additions & 69 deletions development/new_widgets/scrolledtext.py
Original file line number Diff line number Diff line change
@@ -1,70 +1,64 @@
"""
This widget is adapted from `tkinter.scrolledtext.ScrolledText`

The ttkbootstrap.widgets.scrolledtext module provides a class of
the same name which implements a text widget with a vertical
scrollbar that can be styled using the `bootstyle` parameter.
"""

from tkinter import Pack, Grid, Place
from ttkbootstrap import Frame, Text, Scrollbar
from tkinter.constants import RIGHT, LEFT, Y, BOTH

class ScrolledText(Text):
"""A text widget that contains a vertical scrollbar on the right
which can be styled with the `bootstyle` parameter. You can add
a focus color border effect by setting the `highlightbackground`
option.

Configuration options are passed to the `Text` widget. A `Frame`
widget is inserted between the `master` and the `Text` to hold the
`Scrollbar` widget. Most method calls are inherited from the `Text`
widget; however, `Pack`, `Grid`, and `Place` methods are redirected
to the `Frame` widget.

See the original [Python documentation](https://docs.python.org/3/library/tkinter.scrolledtext.html)
for additional information on usage and settings.

_This widget is adapted from `tkinter.scrolledtext.ScrolledText`_
"""
def __init__(self, master=None, **kw):
if 'bootstyle' in kw:
bootstyle = kw.pop('bootstyle')
else:
bootstyle = None
self.frame = Frame(master)
self.vbar = Scrollbar(self.frame, bootstyle=bootstyle)
self.vbar.pack(side=RIGHT, fill=Y)

kw.update({'yscrollcommand': self.vbar.set})
#if 'font' not in
Text.__init__(self, self.frame, highlightthickness=0, **kw)
self.pack(side=LEFT, fill=BOTH, expand=True)
self.vbar['command'] = self.yview

text_meths = vars(Text).keys()
methods = vars(Pack).keys() | vars(Grid).keys() | vars(Place).keys()
methods = methods.difference(text_meths)

for m in methods:
if m[0] != '_' and m != 'config' and m != 'configure':
setattr(self, m, getattr(self.frame, m))

self.config = self.configure # alias

def __str__(self):
return str(self.frame)

def configure(self, cnf=None, **kwargs):
# get configuration
if cnf == 'bootstyle':
return self.vbar.cget('style')
elif cnf is not None:
return self.cget(cnf)

# set configuration
if 'bootstyle' in kwargs:
bootstyle = kwargs.pop('bootstyle')
self.vbar.configure(bootstyle=bootstyle)
self.configure(cnf=cnf, **kwargs)
import ttkbootstrap as ttk
from ttkbootstrap.constants import *


class ScrolledText(ttk.Frame):

"""A text widget with a vertical scrollbar."""

def __init__(self, master=None, padding=2, bootstyle=DEFAULT, **kwargs):
"""
Parameters:

master (Widget):
The parent widget.

padding (int):
The amount of empty space to create on the outside of the
widget.

bootstyle (str):
A style keyword used to set the color and style of the vertical
scrollbar. Available options include -> primary, secondary,
success, info, warning, danger, dark, light.

**kwargs (Dict[str, Any]):
Other keyword arguments passed to the `Text` widget.
"""
super().__init__(master, padding=padding)

# setup text widget
kwargs['master'] = self
self._text = ttk.Text(**kwargs)
self._text.pack(side=LEFT, fill=BOTH, expand=YES)

# delegate text methods to frame widget
for method in vars(ttk.Text).keys():
if any(['pack' in method, 'grid' in method, 'place' in method]):
pass
else:
setattr(self, method, getattr(self._text, method))

# setup scrollbar
self._scrollbar = ttk.Scrollbar(
master=self,
bootstyle=bootstyle,
command=self._text.yview
)
self._scrollbar.pack(side=RIGHT, fill=Y)
self._text.configure(yscrollcommand=self._scrollbar.set)


if __name__ == '__main__':

app = ttk.Window()

nb = ttk.Notebook(app)
t = ScrolledText(nb, padding=20, bootstyle='info-round')
t.insert(END, 'What is this?')
nb.add(t, text="My Text")
nb.pack()
app.mainloop()



24 changes: 24 additions & 0 deletions development/tests/scrolled_widgets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import ttkbootstrap as ttk
from ttkbootstrap.constants import *
from ttkbootstrap.scrolled import ScrolledText, ScrolledFrame

# app = ttk.Window()

# st = ScrolledText(app, padding=20, width=30, height=10, hbar=True)
# st.pack(fill=BOTH, expand=YES)

# for x in range(25):
# st.insert(END, f'This is a really long line of text... it is {x+1} of 25!\n')

# app.mainloop()


app = ttk.Window()

sf = ScrolledFrame(app)
sf.pack(fill=BOTH, expand=YES, padx=10, pady=10)

for x in range(20):
ttk.Button(sf, text=f"button {x}").pack(anchor=W)

app.mainloop()
9 changes: 9 additions & 0 deletions docs/api/icons/emoji.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Emoji

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

7 changes: 4 additions & 3 deletions docs/api/icons.md → docs/api/icons/icon.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# icons module
# Icon

::: ttkbootstrap.icons
::: ttkbootstrap.icons.Icon
selection:
filters: ["!^_", "^__init__"]
rendering:
heading_level: 2

show_root_heading: true

35 changes: 27 additions & 8 deletions docs/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
ttkbootstrap is a wrapper on tkinter. Any widget or function not defined
specifically in this library can be found in [other references](#other-references).

## 📟 dialogs module
## 💬 dialogs module
This module contains various base dialog base classes (ending in "Dialog")
that can be used to create custom dialogs for the end user. These base
classes serve as the basis for the pre-defined static helper methods in
Expand All @@ -17,6 +17,22 @@ pre-defined message and query dialog configurations.
❯ [MessageBox](dialogs/messagebox.md)
❯ [QueryBox](dialogs/querybox.md)

## 😉 icons module
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)
❯ [Icon](icons/icon.md)

## 📜 scrolled module
This module contains various scrolled widgets such as `ScrolledText` and
`ScrolledFrame`.

❯ [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 @@ -30,6 +46,16 @@ docs are here for your reference.
❯ [StyleBuilderTTK](style/stylebuilderttk.md)
❯ [Bootstyle](style/bootstyle.md)

## 🛎️ [toast module](toast.md)
This module has a class called `ToastNotification` which provides a
semi-transparent popup window for temporary alerts or messages.

## 📝 [tooltip module](tooltip.md)
This module contains a class of the same name that provides a
semi-transparent tooltip popup window that shows text when the
mouse is hovering over the widget and closes when the mouse is no
longer hovering over the widget.

## ☑️ widgets module
This module contains the custom ttkbootstrap widgets linked below.

Expand All @@ -46,14 +72,7 @@ convenient api for initial application startup. This also applies to the
❯ [Window](window/window)
❯ [Toplevel](window/toplevel)

## 😉 [icons module](icons.md)
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`.

❯ [Icon](icons/#ttkbootstrap.icons.Icon)
❯ [Emoji](icons/#ttkbootstrap.icons.Emoji)

## ⚙️ [utility module](utility.md)
This module includes various utility functions that may or may not be useful
to the end user. Click the header to read more.
Expand Down
9 changes: 9 additions & 0 deletions docs/api/scrolled/scrolledframe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# ScrolledFrame

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

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

::: ttkbootstrap.scrolled.ScrolledText
selection:
filters: ["!^_", "^__init__"]
rendering:
heading_level: 2
show_root_heading: true
5 changes: 3 additions & 2 deletions gallery/text_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"""
import ttkbootstrap as ttk
from ttkbootstrap.constants import *
from ttkbootstrap.scrolled import ScrolledText
from tkinter.filedialog import askopenfilename
from tkinter.scrolledtext import ScrolledText


class TextReader(ttk.Frame):
Expand All @@ -23,7 +23,8 @@ def create_widget_elements(self):
master=self,
highlightcolor=style.colors.primary,
highlightbackground=style.colors.border,
highlightthickness=1
highlightthickness=1,
autohide=True
)
self.textbox.pack(fill=BOTH)
default_txt = "Click the browse button to open a new text file."
Expand Down
7 changes: 6 additions & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,12 @@ nav:
- api/dialogs/fontdialog.md
- api/dialogs/messagebox.md
- api/dialogs/querybox.md
- 'icons module': api/icons.md
- 'icons module':
- api/icons/emoji.md
- api/icons/icon.md
- 'scrolled module':
- api/scrolled/scrolledframe.md
- api/scrolled/scrolledtext.md
- 'style module':
- api/style/bootstyle.md
- api/style/colors.md
Expand Down
3 changes: 2 additions & 1 deletion src/ttkbootstrap/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import ttkbootstrap as ttk
from ttkbootstrap.constants import *
from ttkbootstrap.dialogs import Messagebox
from ttkbootstrap.scrolled import ScrolledText


def setup_demo(master):
Expand Down Expand Up @@ -141,7 +142,7 @@ def change_theme(e):
nb.add(ttk.Frame(nb), text="Tab 5")

# text widget
txt = ttk.Text(master=lframe, height=5, width=50, wrap="none")
txt = ScrolledText(master=lframe, height=5, width=50, autohide=True)
txt.insert(END, ZEN)
txt.pack(side=LEFT, anchor=NW, pady=5, fill=BOTH, expand=YES)
lframe_inner = ttk.Frame(lframe)
Expand Down