This is a work-in-progress project. Although all the basic widgets and other classes already exist in my local repo, they are not yet ready to push them to GitHub. Anything that's here on GitHub, could be changed, so you shouldn't use it in any of your projects.
The goal of Tukaan is to be an easy-to-use, powerful and pythonic GUI framework.
In the beginning I just wanted to create a alternative framework to Tkinter, so I don't have to use it. Now it's a much bigger project, I want to make it a full, modern GUI framework.
Tkinter is just a wrapper around Tk, that is so thin, that you can see through it, and even has holes on it. If you have ever used Tkinter, you know, it's kinda dumb. There are a lot of things not implemented in Tkinter, you can only access them with Tcl calls. Tukaan has everything you could need, and maybe even more.
In Tcl almost everything is represented as strings, and Tkinter doesn't convert them to Python objects, so you have to do that yourself. If you mess something up, it won't raise a Python exception, but Tcl a error, which you don't know what's wrong even if you know the Tcl language. Tkinter also looks awful by default. You can change this, if you use the the Ttk extensions. But why should you use extensions to make your GUI not look like it came from the 90's?
With Tukaan this is completely different. With it, the app looks native by default on Windows and on Mac OS as well. Unfortunately this isn't possible on Linux, but it uses a better theme than the Tk default.
import tukaan
class MyApp(tukaan.App):
def __init__(self):
tukaan.App.__init__(self, title="My nice little Tukaan app")
self.position = "center"
self.button = tukaan.Button(self, text="Button")
self.button.callback = lambda: print("ok")
self.button.layout.grid(row=0, col=0, margin=(1, 2, 3, 4))
def main():
MyApp().run()
if __name__ == "__main__":
main() You can specify cells for the grid layout in a list of sublists to set rows, columns, rowspans, and columnspans for the widgets, making it super easy and apparent what the layout will look like.
import tukaan
class MyApp(tukaan.App):
def __init__(self):
tukaan.App.__init__(self)
self.layout.grid_cells = [["button", "button"], ["label", "entry"]]
self.button = tukaan.Button(self, text="Button")
self.label = tukaan.Label(self, text="Label")
self.entry = tukaan.Entry(self)
self.button.layout.grid(cell="button", align="stretch")
self.label.layout.grid(cell="label", align="stretch")
self.entry.layout.grid(cell="entry", align="stretch")
def main():
MyApp().run()
if __name__ == "__main__":
main()Extending widgets isn’t that hard, so you just need to template the rows or columns, and you need to set stretchiness on the widget.
import tukaan
class MyApp(tukaan.App):
def __init__(self):
tukaan.App.__init__(self)
self.layout.grid_col_template = (1, 0, 2)
for col, (name, text) in enumerate(zip(
("button_1", "button_2", "button_3"),
("Button 1", "Button 2", "Button 3")
)):
setattr(self, name, tukaan.Button(self, text=text))
getattr(self, name).layout.grid(row=0, col=col, align="stretch")
def main():
MyApp().run()
if __name__ == "__main__":
main()You can easily set margins for your widgets ...
the same for every side
widget.layout.grid(cell="some_cell", margin=(2))different horizontal and vertical
widget.layout.grid(cell="some_cell", margin=(2, 10))2 on top, 10 horizontally, 6 on bottom
widget.layout.grid(cell="some_cell", margin=(2, 10, 6))2 on top, 10 on right, 6 on bottom and 4 on left
widget.layout.grid(cell="some_cell", margin=(2, 10, 6, 4))... and you can simply modify any attributes
widget.layout.cell = "other_cell"import tukaan
with tukaan.App(title="tukaan.App with context manager") as app:
button = tukaan.Button(app, text="Button", on_click=lambda: print("stuff"))
button.layout.grid()TODO: currently not working with images
print(tukaan.Clipboard.get())
# or
print(tukaan.Clipboard.content)print("User last active", tukaan.App().user_last_active, "seconds ago.")FIXME: For some reason it doesn't work sometimes
app = tukaan.App()
app.position = "center">>> color = tukaan.Color("#007fff")
>>> print(color.rgb)
(0, 127, 255)
>>> print(color.hsv)
(210, 100, 100)
>>> print(color.cmyk)
(100, 50, 0, 0)>>> screen = tukaan.Screen() # you don't need to instantiate it
>>> print(screen.width)
1920
>>> print(screen.height)
1080
>>> print(screen.dpi)
72>>> cursor = tukaan.Cursor # not instantiate it, just have a reference
>>> print(cursor.x)
123
>>> print(cursor.y)
456
>>> cursor.x = 456 # cursor moved
>>> print(cursor.position)
(456, 456)-
Logo design:
Inspired by Tajulislam12's design:
https://dribbble.com/shots/14487668-toucan-logo-design-Icon -
Many thing in Tukaan is based on:
- Akuli's Teek (TODO: which parts and why?)
- Ckyiu's TkZero
- one of my private Gists