-
Notifications
You must be signed in to change notification settings - Fork 32
Some simple improvements #80
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
Open
rdbende
wants to merge
33
commits into
TkinterEP:master
Choose a base branch
from
rdbende:some-improvements
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
551a19c
Create NumberEntry widget
rdbende a6db0b3
Change the default hover-cursor to hand2
rdbende 7611f2a
Change the movement cursor to fleur
rdbende 61a46c5
Add NumberEntry to __init__.py
rdbende 8941ab3
Fixed portability issues
rdbende 8488995
Restore cursor
rdbende 8b614d2
Restore linklabel
rdbende 9584d3f
Add __getitem__, __setitem__ and configure
rdbende af42360
Update AUTHORS.md
rdbende a4af566
Create example for NumberEntry
rdbende 439323e
Create unittest for NumberEntry
rdbende 19f361e
Add NumberEntry to sphinx documentation
rdbende acdbec5
Update AUTHORS.md
rdbende fb2dd12
Fixed fatal config bug
rdbende e5d60f3
Update __init__.py
rdbende de2d5c2
Update __init__.py
rdbende d2fa5e6
Update ttkwidgets.rst
rdbende 28d339c
Update __init__.py
rdbende d7891cb
Update AUTHORS.md
rdbende e98f416
Delete test_numberentry.py
rdbende a386adf
Delete example_numberentry.py
rdbende 7806fee
Delete numberentry.py
rdbende c6e7ab8
native cursors, virtual event, colors
rdbende 32ed8a4
Change exchange cursor to fleur
rdbende e80986d
ToggledFrame improved
rdbende e8c3e0d
Merge branch 'master' into some-improvements
rdbende 6e8cf44
Update LinkLabel
rdbende 364021d
Update LinkLabel tests
rdbende 040b13e
State changes as required by this GPL license
rdbende 3477879
Remove unnecessary variable
rdbende d3a67db
Fix LinkLabel test
rdbende 12560cf
Update ToggledFrame stuff
rdbende 3f8ac80
Use keyword arguments with default instead of kwargs.pop
rdbende File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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
This file contains hidden or 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,26 +1,36 @@ | ||
| # Copyright (c) RedFantom 2017 | ||
| # For license see LICENSE | ||
| from ttkwidgets.frames import ToggledFrame | ||
| from tests import BaseWidgetTest | ||
| import tkinter as tk | ||
|
|
||
| from tests import BaseWidgetTest | ||
| from ttkwidgets.frames import ToggledFrame | ||
|
|
||
|
|
||
| class TestToggledFrame(BaseWidgetTest): | ||
| def test_toggledframe_init(self): | ||
| frame = ToggledFrame(self.window) | ||
| frame.pack() | ||
| self.window.update() | ||
|
|
||
| def test_toggledframe_open(self): | ||
| frame = ToggledFrame(self.window) | ||
| frame.pack() | ||
| self.window.update() | ||
| frame.toggle() | ||
| self.assertTrue(frame._open) | ||
| assert frame.opened | ||
|
|
||
| def test_toggledframe_open_close(self): | ||
| frame = ToggledFrame(self.window) | ||
| frame.pack() | ||
| self.window.update() | ||
| frame.toggle() | ||
| self.assertTrue(frame._open) | ||
| frame.toggle() | ||
| self.assertFalse(frame._open) | ||
| self.window.update() | ||
| assert frame.opened | ||
| frame.close() | ||
| self.window.update() | ||
| assert not frame.opened | ||
| frame.open() | ||
| self.window.update() | ||
| assert frame.opened | ||
| frame._button.invoke() | ||
| self.window.update() | ||
| assert not frame.opened | ||
This file contains hidden or 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 |
|---|---|---|
|
|
@@ -2,13 +2,18 @@ | |
| Author: RedFantom | ||
| License: GNU GPLv3 | ||
| Source: This repository | ||
|
|
||
| Improved by rdbende | ||
| """ | ||
|
|
||
| import tkinter as tk | ||
| from pathlib import Path | ||
| from tkinter import ttk | ||
| import os | ||
| from PIL import Image, ImageTk | ||
rdbende marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| from ttkwidgets.utilities import get_assets_directory | ||
|
|
||
| assets_dir = Path(get_assets_directory()) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like the use of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, I thought I might need it elsewhere, but it turns out I didn't. |
||
|
|
||
|
|
||
| class ToggledFrame(ttk.Frame): | ||
| """ | ||
|
|
@@ -17,44 +22,98 @@ class ToggledFrame(ttk.Frame): | |
| :ivar interior: :class:`ttk.Frame` in which to put the widgets to be toggled with any geometry manager. | ||
| """ | ||
|
|
||
| def __init__(self, master=None, text="", width=20, compound=tk.LEFT, **kwargs): | ||
| def __init__(self, master=None, *, text=None, cursor="arrow", width=20, **kwargs): | ||
| """ | ||
| Create a ToggledFrame. | ||
|
|
||
| :param master: master widget | ||
| :type master: widget | ||
| :param text: text to display next to the toggle arrow | ||
| :param text: text to in the header of the ToggledFrame | ||
| :type text: str | ||
| :param width: width of the closed ToggledFrame (in characters) | ||
| :type width: int | ||
| :param compound: "center", "none", "top", "bottom", "right" or "left": | ||
| position of the toggle arrow compared to the text | ||
| :type compound: str | ||
| :param cursor: cursor that appears on the ToggledFrame's button | ||
| :type cursor: str | ||
| :param kwargs: keyword arguments passed on to the :class:`ttk.Frame` initializer | ||
| """ | ||
| self._open = tk.BooleanVar(value=False) | ||
|
|
||
| ttk.Frame.__init__(self, master, **kwargs) | ||
| self._open = False | ||
| self.__checkbutton_var = tk.BooleanVar() | ||
| self._open_image = ImageTk.PhotoImage(Image.open(os.path.join(get_assets_directory(), "open.png"))) | ||
| self._closed_image = ImageTk.PhotoImage(Image.open(os.path.join(get_assets_directory(), "closed.png"))) | ||
| self._checkbutton = ttk.Checkbutton(self, style="Toolbutton", command=self.toggle, | ||
| variable=self.__checkbutton_var, text=text, compound=compound, | ||
| image=self._closed_image, width=width) | ||
| self.interior = ttk.Frame(self, relief=tk.SUNKEN) | ||
| self._grid_widgets() | ||
|
|
||
| def _grid_widgets(self): | ||
| self._checkbutton.grid(row=0, column=0, sticky="we") | ||
|
|
||
| def toggle(self): | ||
| """Toggle :obj:`ToggledFrame.interior` opened or closed.""" | ||
| if self._open: | ||
| self._open = False | ||
| self.__checkbutton_var.set(False) | ||
| self.interior = ttk.Frame(self) | ||
|
|
||
| self._open_image = tk.PhotoImage(file=assets_dir / "open.png") | ||
| self._closed_image = tk.PhotoImage(file=assets_dir / "closed.png") | ||
|
|
||
| self._button = ttk.Checkbutton( | ||
| self, | ||
| style="Toolbutton", | ||
| compound="right", | ||
| cursor=cursor, | ||
| image=self._closed_image, | ||
| text=text, | ||
| variable=self._open, | ||
| command=self._toggle_when_clicked, | ||
| width=width, | ||
| ) | ||
| self._button.grid(row=0, column=0, sticky="ew") | ||
|
|
||
| def __getitem__(self, key): | ||
| return self.cget(key) | ||
|
|
||
| def __setitem__(self, key, value): | ||
| self.configure(**{key: value}) | ||
|
|
||
| def _toggle_when_clicked(self): | ||
| # when clicking the checkbutton it inverts its variable, so we can't simply use self.toggle | ||
| if self._open.get(): | ||
| self.interior.grid(row=1, column=0, sticky="nswe") | ||
| self._button.config(image=self._open_image) | ||
| self.event_generate("<<ToggledFrameOpened>>") | ||
| else: | ||
| self.interior.grid_forget() | ||
| self._checkbutton.config(image=self._closed_image) | ||
| self._button.config(image=self._closed_image) | ||
| self.event_generate("<<ToggledFrameClosed>>") | ||
|
|
||
| def open(self): | ||
| self.interior.grid(row=1, column=0, sticky="nswe") | ||
| self._open.set(True) | ||
| self._button.config(image=self._open_image) | ||
| self.event_generate("<<ToggledFrameOpened>>") | ||
|
|
||
| def close(self): | ||
| self.interior.grid_forget() | ||
| self._open.set(False) | ||
| self._button.config(image=self._closed_image) | ||
| self.event_generate("<<ToggledFrameClosed>>") | ||
|
|
||
| def toggle(self): | ||
| if self._open.get(): | ||
| self.close() | ||
| else: | ||
| self._open = True | ||
| self.__checkbutton_var.set(True) | ||
| self.interior.grid(row=1, column=0, sticky="nswe") | ||
| self._checkbutton.config(image=self._open_image) | ||
| self.open() | ||
|
|
||
| @property | ||
| def opened(self): | ||
| return self._open.get() | ||
|
|
||
| def configure(self, **kwargs): | ||
| """Configure resources of the widget""" | ||
| button_options = { | ||
| key: kwargs.pop(key) for key in ("cursor", "text", "width") if key in kwargs | ||
| } | ||
| self._button.configure(**button_options) | ||
| ttk.Frame.configure(self, **kwargs) | ||
|
|
||
| config = configure | ||
|
|
||
| def cget(self, key): | ||
| """Return the resource value for a KEY given as string""" | ||
| if key in {"cursor", "text", "width"}: | ||
| return self._button.cget(key) | ||
| else: | ||
| return ttk.Frame.cget(self, key) | ||
|
|
||
| def keys(self): | ||
| """Return a list of all resource names of this widget""" | ||
| return sorted(ttk.Frame.keys(self) + ["text"]) | ||
This file contains hidden or 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
This file contains hidden or 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
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are good reasons to use
assertTrue,assertFalse,assertEquals, and so on, so it's important that they are not changed. See also here.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I use Pytest as test runner, which prefers the
assertkeyword, and logs usable output with it, but I see we're using Nose here, so I'll rewrite it.