{"id":17241973,"url":"https://github.com/mtkennerly/tkup","last_synced_at":"2025-04-14T03:22:10.684Z","repository":{"id":43612611,"uuid":"123754853","full_name":"mtkennerly/tkup","owner":"mtkennerly","description":"Hierarchical Tkinter wrapper for Python","archived":false,"fork":false,"pushed_at":"2024-03-17T03:10:21.000Z","size":63,"stargazers_count":19,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-21T00:20:10.576Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mtkennerly.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-03-04T03:54:41.000Z","updated_at":"2023-08-23T12:59:43.000Z","dependencies_parsed_at":"2023-01-22T12:01:31.514Z","dependency_job_id":null,"html_url":"https://github.com/mtkennerly/tkup","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtkennerly%2Ftkup","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtkennerly%2Ftkup/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtkennerly%2Ftkup/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtkennerly%2Ftkup/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mtkennerly","download_url":"https://codeload.github.com/mtkennerly/tkup/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248814048,"owners_count":21165671,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-15T06:11:56.282Z","updated_at":"2025-04-14T03:22:10.653Z","avatar_url":"https://github.com/mtkennerly.png","language":"Python","funding_links":[],"categories":["others"],"sub_categories":[],"readme":"\n# tkup\ntkup is a thin wrapper around standard Tkinter widgets, allowing you to write\ncode that visually reflects the widget hierarchy. It doesn't try to reinvent\nthe wheel and just helps you use normal Tkinter in a streamlined way.\n\nTypical Tkinter code is flat, even though it represents a heavily nested\nstructure, which makes it difficult to quickly read and understand the true\norganization of the GUI. You must also explicitly assign each widget's master,\nwhich is error-prone and verbose:\n\n```python\nimport tkinter as tk\nfrom tkinter import ttk\n\napp = tk.Tk()\napp.title(\"Demo\")\n\nouter_frame = ttk.Frame(app)\nouter_frame.grid()\nhi_button = ttk.Button(outer_frame, text=\"hi\")\nhi_button.grid()\n\napp.mainloop()\n```\n\ntkup solves this by using nested with-statements. There are factory functions\nfor each kind of widget, and you can use them as context managers so that\nnested master widgets are automatically assigned. Post-instantiation calls,\nlike gridding, can be accomplished two ways, most traditionally by naming the\nyielded value:\n\n```python\nfrom tkup import GUI\n\napp = GUI()\n\nwith app.root() as root:\n    root.title(\"Demo\")\n    with app.frame() as outer_frame:\n        outer_frame.grid()\n        with app.button(text=\"hi\") as hi_button:\n            hi_button.grid()\n\napp.run()\n```\n\nHowever, naming every single widget just to grid it can be tiresome.\nInspired by Kotlin's implicit creation of the `it` variable in lambdas,\nthe GUI class provides an `it` method which returns the current master widget,\nand there is an additional convenience method called `with_it` which returns\nthe GUI instance and its `it` method for quick assignment to variables:\n\n```python\nfrom tkup import GUI\n\napp, it = GUI().with_it()\n\nwith app.root():\n    it().title(\"Demo\")\n    with app.frame():\n        it().grid()\n        with app.button(text=\"hi\"):\n            it().grid()\n\napp.run()\n```\n\ntkup prefers themed (ttk) widgets wherever available. If you want to use\nclassic widgets, or if you want to use a custom subclass of `tkinter.Widget`,\nthen you can use the GUI `widget` method and pass in the type to instantiate:\n\n```python\nimport tkinter as tk\nfrom tkup import GUI\n\napp = GUI()\n\nwith app.root():\n    with app.widget(tk.Button, text=\"foo\"):\n        ...\n```\n\n## Installation\n```\npip install tkup\n```\n\ntkup supports Python 3.5 and higher.\n\n## Development\nPlease refer to [CONTRIBUTING.md](CONTRIBUTING.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmtkennerly%2Ftkup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmtkennerly%2Ftkup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmtkennerly%2Ftkup/lists"}