tukaan / tukaan Goto Github PK
View Code? Open in Web Editor NEWContemporary GUI framework for Python based on the ancient Tcl/Tk
Home Page: https://tukaan.github.io
License: MIT License
Contemporary GUI framework for Python based on the ancient Tcl/Tk
Home Page: https://tukaan.github.io
License: MIT License
When I create an app with tkinter I normally will start the file with from tkinter import *
so it gets rid of the hassle of importing labels and buttons and whatnot. We need to make that compatible and work with Tukaan. Great job on the release by the way!
@rdbende I'm unsure how to use fonts with Tukaan labels. How should I do this?
I just follow the example given in ReadMe to try this module at the first time.
import tukaan
app = tukaan.App("My first Tukaan app")
app.run()
Then I get this error.
(env) D:\Desktop\coding\sandbox>d:/Desktop/coding/discordpy/env/Scripts/python.exe d:/Desktop/coding/sandbox/tukaan.py
Traceback (most recent call last):
File "d:\Desktop\coding\sandbox\tukaan.py", line 1, in <module>
import tukaan
File "d:\Desktop\coding\sandbox\tukaan.py", line 3, in <module>
app = tukaan.App("My first Tukaan app")
AttributeError: partially initialized module 'tukaan' has no attribute 'App' (most likely due to a circular import)
I am new to this module and I have no idea about why would this happens.
Sorry for my incoveniences causes.
Hasn't been updated in a while and I'd like to try some of the new features
Tukaan's Screen
and ScreenDistance
objects are really nice and useful, but based on this SO question, they may not work at all on dual monitor setups.
Another problem is that Tcl/tk doesn't know the real ppi, only dpi, so ScreenDistance works well only if user doesn't use xrandr --dpi <not ppi>
.
I have no better idea than what teek does.
Usually you don't need a named, mutable font object, just an object to specify the widget font, so a tcl namedfont is a total waste of memory. On the other hand it isn't good to have multiple font classes to different tasks.
Important: when using MacOS having a good DockMenu menu is incredibly important. I propose that we create a good system for this as it does not seem to be built into tk. See my stackoverflow question for more detail. This is also an issue for windows so setting up a good system is important to get done at some point.
A scrollable frame.
scrollview = ScrollView(
app,
overflow=(False, "auto"),
padding=(1, 2, 3, 4),
)
tukaan.TextBox
widgets
Requires: tukaan.Image
Documentation: text(3tk)
Features to be implemented:
Font management in Tk (and in Tkinter too) is a big pile of shitt
In Tukaan it shouldn't be
Implement image support for tukaan.Button
and tukaan.Label
widgets
Requirement: tukaan._images._image_converter_class
Features to be implemented:
tukaan.TabView
and tukaan.TabView.Tab
widgets
Requires other widget: tukaan.Frame
Documentation: ttk_notebook(3tk)
Features to be implemented:
Lines 56 to 70 in fcf7ff9
$ cat test.py
import tukaan, tkinter, timeit
def asdf():
_ = tukaan.App()
_.quit()
def qwer():
_ = tkinter.Tk()
_.quit()
print(timeit.timeit(asdf, number=100))
print(timeit.timeit(qwer, number=100))
$ python3 test.py
can't invoke "event" command: application has been destroyed
while executing
"event generate $w <<ThemeChanged>>"
(procedure "ttk::ThemeChanged" line 6)
invoked from within
"ttk::ThemeChanged"
[...] * 99
10.320173018000037 # tukaan
2.983373939999933 # tkinter
without those lines, tukaan is only between 2.9 and 3.3 seconds
tukaan.Frame
widget
Required widgets: tukaan.ScrollBar
Documentation: ttk_frame(3tk)
Features to be implemented:
overflow
attributetukaan.CheckBox
widget
Requirements: Boolean control variable
Documentation: ttk_checkbutton(3tk)
Features to be implemented:
tukaan._images._image_converter_class
, tukaan.Image
, tukaan.Icon
and tukaan.IconFactory
classes
Images work only with PIL, because Tk images still suck.
A widget to display images
image = PIL.Image.open("img.jpg")
image_widget = tukaan.Image(root, image)
Can also be used for a button, or anything else
image = PIL.Image.open("img.jpg")
image_button = tukaan.Button(root, image=image)
Icon
class WITHOUT PIL, so it's fast, but immutable, only png
icon = tukaan.Icon("icon.png")
icon_button = tukaan.Button(root, image=icon)
IconFactory
is basically an object to collect Icon
s
icons = tukaan.IconFactory(light_theme="./dark_icons", dark_theme="./light_icons")
icon_button = tukaan.Button(root, image=icons.get("new_tab"))
Can we create a widget that shows text when widgets are hovered over?
Would be nice to have:
How do I create menubars? Can we make it possible to create menubars before the application window is created in order to have an instant loading of it?
TODO:
Implementation:
KDialog
if availableZenity
if availablenotify-send
if availableI cant run any Tukaan code on windows? Help
import tukaan
# Create window
app = tukaan.App("Test TabView widget")
# Create tabview
tabview = tukaan.TabView(app)
tabview.grid()
# Create tabs
tab_1 = tabview.Tab("Tab 1")
tab_2 = tabview.Tab("Tab 2")
# Add tab contents
tukaan.Button(tab_1, "Button in tab 1").grid() # You can display it inline, but then you can't access the object later
tukaan.Button(tab_2, "Button in tab 2").grid()
app.run()
LookAndFeel
objectsystem_theme
system_colors
tukaan.LookAndFeel.system_theme
# LookAndFeel.system_theme returns:
# - 'dark' or 'light' on macOS and MS Windoze
# - current Gtk theme if available (not yet implememted)
tukaan.LookAndFeel.system_colors
# Returns a namedtuple containing the system colors
AquaTheme
Win32Theme
KolorScheme
NativeTheme
from tukaan import App, AquaTheme, GtkTheme, KolorScheme, Win32Theme
app = App()
app.theme = AquaTheme # macOS only
app.theme = Win32Theme # MS Windows only
app.theme = GtkTheme # Tries to use native Gtk 2.0 theme, Linux only
app.theme = KolorScheme # Uses Clam theme with KDE Plasma colorscheme, needs `kreadconfig5`
See #71
CssTheme
classTheme collection module with Tcl themes. See first few comments of #74
tukaan.Entry
widget
Documentation: ttk_entry(3tk)
Features to be implemented:
A group of buttons, similar to RadioGroup
. The button labels and callbacks could be specified in a dict, like items={"Text": do_something}
.
The leftmost button should have the Left.TButton
style, the rightmost Right.TButton
, and all the others Middle.TButton
(similar stuff when the orientation is vertical), this way it's possible to do, that only the outer buttons have round corners. (I think my forest theme has this feature, but it might be only in one of my local branches).
TODO:
tkdnd
to Dropp
submoduletkdnd
to Dropp
libtukaan
Tooltip has some issues on Mac and I have some ideas. First and foremost is the usage of the toplevel:
Proposed code:
@classmethod
def schedule(cls, widget: str) -> None:
cls._can_show = True
message = cls._widgets.get(widget)
if message is None:
return
Tcl.call(None, ".tooltip.label", "configure", "-text", message)
cls._after_id = Tcl.call(str, "after", 500, cls._show_cmd, widget)
@classmethod
def show(cls, widget: str) -> None:
if not cls._can_show:
return
owner_x = Tcl.call(int, "winfo", "rootx", widget)
owner_width = Tcl.call(int, "winfo", "reqwidth", widget)
tip_width = Tcl.call(int, "winfo", "reqwidth", ".tooltip")
tip_x = owner_x + owner_width // 2 - tip_width // 2
owner_y = Tcl.call(int, "winfo", "rooty", widget)
tip_height = Tcl.call(int, "winfo", "reqheight", ".tooltip")
tip_y = owner_y - tip_height - 5
if tip_y <= Tcl.eval(int, f"winfo rooty [winfo toplevel {widget}]"):
tip_y = owner_y + Tcl.call(int, "winfo", "reqheight", widget) + 5
Tcl.call(None, "wm", "geometry", ".tooltip", f"+{tip_x}+{tip_y}")
Tcl.call(None, "wm", "deiconify", ".tooltip")
Images:
MessageCatalog
objecttukaan.ScrollBar
widget
Documentation: ttk_scrollbar(3tk)
Features to be implemented:
I get this error idk why
tukaan.exceptions.TclError: Serif: Unsupported platform windows-x64
Ohh, I hate writing tests...
But there are so much bug and I always mess up something, so it'd be useful.
Terminal-like widget thingy, that allows you to run basic commands.
I don't want it to be a fully functional terminal, as it would require a lot of work, but it'd be useful for running basic commands.
Example usage:
term = tukaan.TerminalView(
app,
cwd=Path.home(),
prompt="{user}@{node}:{cwd}$ ",
input=True,
output=True,
stdin=True,
stdout=True,
stderr=True,
)
In tukaan.media
or tukaan.audio
submodule.
TODO:
widget.layout.grid(row=1, col=1, margin=(1, 2, 3, 4))
Parameter | Description |
---|---|
row | row |
col | column |
rowspan | rowspan |
colspan | columnspan |
margin | human understandable expression for padx and pady |
hor_align | horizontal stickiness see below |
vert_align | vertical stickiness see below |
Horizontal align | Vertical align | Tk sticky value |
---|---|---|
None | None | |
None | top | n |
None | bottom | s |
right | None | e |
left | None | w |
left | top | nw |
right | top | ne |
left | bottom | sw |
right | bottom | se |
stretch | top | new |
stretch | None | ew |
stretch | bottom | sew |
left | stretch | nsw |
None | stretch | ns |
right | stretch | nse |
stretch | stretch | nsew |
widget.layout.position(x=10, y=10, width=ScreenDistance(4, "cm"))
Parameter | Description |
---|---|
x | x, if you give it in percents, it will be relx |
y | y, if you give it in percents, it will be rely |
width | width, if you give it in percents, it will be relwidth |
height | height, if you give it in percents, it will be relheight |
anchor | anchor |
In tkinter you can do things like this:
widget.place(relx=1, x=-20)
which will place the widget 20 pixels before 100%, because Tukaan don't supports explicit relative sizes and positions you cant do this. could be solved by a move method
e.g.
widget.layout.move(x=-20)
# and also for grid:
widget.layout.move(row=-2)
slaves
command into the child_stats
of the widget )The problem is in the following line:
self.button.layout.grid(row=0, column=0, margin=(1, 2, 3, 4))
There is no column
parameter in the Grid.grid
method, there is col
instead.
But I wonder, isn't it better to use full names like "column" or "columnspan"?
In css you can do things like this to place an element by grid cell name:
.some__parent {
grid-template-areas:
"label button . ."
"frame frame other other"
"button_1 button_1 other other";
}
.some__widget {
grid-area: other
}
This will place the widget in row: 1
, column: 2
, and will set the column and rowspan.
So in Tukaan instead of this:
some_widget.layout.grid(row=1, col=2, rowspan=2, colspan=2)
you could write this, and cells are already created for the rest of the widgets:
some_parent.layout.grid_cells = [
["label", "button", None, None],
["frame", "frame", "other", "other"],
["button_1", "button_1", "other", "other"],
]
some_widget.layout.grid(cell="other")
.some__parent {
grid-template-columns: 1fr 1fr 1fr 3fr;
grid-template-rows: 0fr 1fr 1fr;
}
some_parent.columnconfigure(index=0, weight=1)
some_parent.columnconfigure(index=1, weight=1)
some_parent.columnconfigure(index=2, weight=1)
some_parent.columnconfigure(index=3, weight=3)
some_parent.rowconfigure(index=0, weight=0)
some_parent.rowconfigure(index=1, weight=1)
some_parent.rowconfigure(index=2, weight=1)
some_parent.layout.grid_column_template = (1, 1, 1, 3)
some_parent.layout.grid_row_template = (0, 1, 1)
Currently at lot of places Tukaan simply re-raises the errors thrown by Tcl, which aren't very informative, and since Tukaan covers so much of the Tk stuff, they are sonetimes not even relevant.
We need to create appropriate exception classes and raise them in these places with descriptive messages.
This will make it much easier to get started, I didnβt even know this had so many options without looking at the code!
tukaan.RadioButton
and tukaan.RadioGroup
widgets
Requirements: control variables
Documentation: ttk_radiobutton(3tk)
Features to be implemented:
RadioButton:
RadioGroup:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.