{"id":15009799,"url":"https://github.com/akascape/tkdial","last_synced_at":"2025-04-09T17:51:55.327Z","repository":{"id":63529186,"uuid":"568411481","full_name":"Akascape/TkDial","owner":"Akascape","description":"Tkinter Dial-Knob widgets","archived":false,"fork":false,"pushed_at":"2024-03-15T17:37:39.000Z","size":110,"stargazers_count":48,"open_issues_count":4,"forks_count":7,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-23T19:51:31.035Z","etag":null,"topics":["python3","tkdial","tkinter","tkinter-canvas","tkinter-dial","tkinter-dial-widget","tkinter-gauge","tkinter-graphic-interface","tkinter-gui","tkinter-gui-library","tkinter-knob","tkinter-library","tkinter-meter","tkinter-python","tkinter-slider","tkinter-widget","tkinter-widgets"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc0-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Akascape.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-11-20T13:05:10.000Z","updated_at":"2025-03-07T21:34:06.000Z","dependencies_parsed_at":"2024-10-12T09:40:52.739Z","dependency_job_id":null,"html_url":"https://github.com/Akascape/TkDial","commit_stats":{"total_commits":31,"total_committers":1,"mean_commits":31.0,"dds":0.0,"last_synced_commit":"23e090bc2c525c3cb3faf6761cefc948404642cf"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Akascape%2FTkDial","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Akascape%2FTkDial/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Akascape%2FTkDial/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Akascape%2FTkDial/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Akascape","download_url":"https://codeload.github.com/Akascape/TkDial/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248083185,"owners_count":21045055,"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":["python3","tkdial","tkinter","tkinter-canvas","tkinter-dial","tkinter-dial-widget","tkinter-gauge","tkinter-graphic-interface","tkinter-gui","tkinter-gui-library","tkinter-knob","tkinter-library","tkinter-meter","tkinter-python","tkinter-slider","tkinter-widget","tkinter-widgets"],"created_at":"2024-09-24T19:28:38.834Z","updated_at":"2025-04-09T17:51:55.298Z","avatar_url":"https://github.com/Akascape.png","language":"Python","readme":"# TkDial\n**This is a library containing some circular rotatory dial-knob widgets for Tkinter. It can be used in place of normal sliders and scale.**\n\n[![PyPI](https://img.shields.io/pypi/v/tkdial)](https://pypi.org/project/tkdial)\n![Platform](https://img.shields.io/powershellgallery/p/Pester?color=blue)\n[![Downloads](https://static.pepy.tech/personalized-badge/tkdial?period=total\u0026units=international_system\u0026left_color=green\u0026right_color=brightgreen\u0026left_text=Downloads)](https://pepy.tech/project/tkdial)\n\n## Installation\n```\npip install tkdial\n```\n\n# Dial Widget\n\n## Usage\n\n**Simple Example:**\n```python\nimport tkinter as tk\nfrom tkdial import Dial\n\napp = tk.Tk()\n\ndial = Dial(app)\ndial.grid(padx=10, pady=10)\n\napp.mainloop()\n```\n![Screenshot1](https://user-images.githubusercontent.com/89206401/202906601-89bd91ed-d685-4a4e-9ddc-7824f278ca4b.png)\n\n### **Example 2**\n```python\nimport tkinter as tk\nfrom tkdial import Dial\n\napp = tk.Tk()\n\n# some color combinations\ncolor_combinations = [(\"yellow\", \"red\"), (\"white\", \"cyan\"), (\"red\", \"pink\"), (\"black\", \"green\"),\n                    (\"white\", \"black\"), (\"blue\", \"blue\"), (\"green\", \"green\"), (\"white\", \"pink\"),\n                    (\"red\", \"black\"), (\"green\", \"cyan\"), (\"cyan\",\"black\"), (\"pink\", \"blue\")]\n\nfor i in range (12):\n    dial = Dial(master=app, color_gradient=color_combinations[i],\n                unit_length=10, radius=40, needle_color=color_combinations[i][1])\n    if i\u003c6:\n        dial.grid(row=1, padx=10, pady=10, column=i)\n    else:\n        dial.grid(row=2, padx=10, pady=10, column=11-i)\n\napp.mainloop()\n```\n![Screenshot2](https://user-images.githubusercontent.com/89206401/202906615-e4c484de-ed79-495e-b12f-d30b9d238eac.png)\n\n### **Example 3**\n\n**Implemented with [CustomTkinter](https://github.com/TomSchimansky/CustomTkinter)**\n\n```python\nimport customtkinter\nfrom tkdial import Dial\n\ncustomtkinter.set_appearance_mode(\"Dark\") \n              \napp = customtkinter.CTk()\napp.geometry(\"350x400\")\n                \napp.grid_columnconfigure((0,1), weight=1)\napp.grid_rowconfigure((0,1), weight=1)\n\nframe_1 = customtkinter.CTkFrame(master=app)\nframe_1.grid(padx=20, pady=20, sticky=\"nswe\")\n\ndial1 = Dial(master=frame_1, color_gradient=(\"green\", \"cyan\"),\n             text_color=\"white\", text=\"Current: \", unit_length=10, radius=50)\ndial1.grid(padx=20, pady=20)\n\ndial2 = Dial(master=frame_1, color_gradient=(\"yellow\", \"white\"),\n             text_color=\"white\", text=\"Position: \", unit_length=10, radius=50)\ndial2.grid(padx=20, pady=20)\n\ndial3 = Dial(master=frame_1, color_gradient=(\"white\", \"pink\"),\n             text_color=\"white\", text=\" \", unit_length=10, radius=50)\ndial3.grid(row=0, column=1, padx=20, pady=20)\n\ndial4 = Dial(master=frame_1, color_gradient=(\"green\", \"green\"),\n             text_color=\"white\", text=\"\", unit_width=15, radius=50)\ndial4.grid(row=1, column=1, padx=20, pady=20)\n\napp.mainloop()                \n```\n![Screenshot 3](https://user-images.githubusercontent.com/89206401/202906638-a1c863b7-54b0-4e7a-9619-415e28b3ab51.png)\n\n## Arguments:\n  | Parameters  | Description |\n  | -------- | ----------- |\n  | _master_ | The master parameter is the parent widget |\n  | _bg_  | The default background color of the dial widget |\n  | _width_ | Define width of the widget manually (optional) |\n  | _height_ | Define height of the widget manually (optional) |\n  | _x_ | Determines the horizontal position of the dial in the canvas |\n  | _y_ | Determines the vertical position of the dial in the canvas |\n  | _start_ |  The start point of the range from where the needle will rotate |\n  | _end_ |  The end point of the range |\n  | _radius_ | Determines the distance of the unit lines between the center and the edge and also the length of the needle line |\n  | _unit_length_ | Specify the length of the lines |\n  | _unit_width_ | Specify the width of the lines |\n  | _unit_color_ |  Specify the color of the unit lines |\n  | _needle_color_ | Specify the color of the needle line |\n  | _color_gradient_ | Specify which color gradient will be used for the units |\n  | _text_ | A string that will be displayed under the dial object with value |\n  | _text_color_ | Specify the color of the text that will be displayed under the dial object |\n  | _text_font_ | Specify the font of the text that will be displayed under the dial object |\n  | _integer_ | A boolean (True/False), displays only the integer value in text if True (default=False) |\n  | _scroll_ | A boolean (True/False), enables mouse scroll in dial (default=True) |\n  | _scroll_steps_ | Number of steps per scroll |\n  | _state_ | Specify the state of the needle |\n  | _command_ | Call a function whenever the needle is rotated |\n  \n### Methods:\n\n  | Methods   | Description |\n  |-----------|-------------|\n  | _.get()_ | get the current value of the dial |\n  | _.set()_ | set the value of the dial |\n  | _.configure()_ | configure parameters of the dial |\n \n# Scroll Knob\n\n## Usage\n**Simple Example**\n```python\nimport tkinter\nfrom tkdial import ScrollKnob\n    \napp = tkinter.Tk()\n\nknob = ScrollKnob(app, start=0, end=100, steps=10)\nknob.grid()\n                \napp.mainloop()      \n```\n![Simple Program](https://user-images.githubusercontent.com/89206401/204139370-73c66402-ec9a-4edc-9891-c63b209fd5e4.png)\n\n### **Different Knob styles:**\n```python\nimport customtkinter\nfrom tkdial import ScrollKnob\n\napp = customtkinter.CTk()\napp.geometry(\"500x500\")\n\nknob1 = ScrollKnob(app, radius=250, progress_color=\"#87ceeb\", steps=10,\n                 border_width=40, start_angle=90, inner_width=1, outer_width=1,\n                 text_font=\"calibri 20\", text_color=\"#87ceeb\", bar_color=\"black\")\nknob1.grid(row=0, column=0)\n\nknob2 = ScrollKnob(app, radius=200, progress_color=\"#7eff00\",\n                 border_width=40, start_angle=90, inner_width=1, outer_width=0,\n                 text_font=\"calibri 20\", text_color=\"#7eff00\", integer=True,\n                 fg=\"#212325\")\nknob2.grid(row=1, column=0)\n\nknob3 = ScrollKnob(app, text=\" \", radius=250, progress_color=\"white\",\n                   bar_color=\"#2937a6\", border_width=30, start_angle=0, inner_width=5,\n                   outer_width=0, text_font=\"calibri 20\", steps=1, text_color=\"white\", fg=\"#303ba1\")\nknob3.grid(row=0, column=1)\n\nknob4 = ScrollKnob(app, text=\" \", steps=10, radius=200, bar_color=\"#242424\", \n                   progress_color=\"yellow\", outer_color=\"yellow\", outer_length=10, \n                   border_width=30, start_angle=270, inner_width=0, outer_width=5, text_font=\"calibri 20\", \n                   text_color=\"white\", fg=\"#212325\")\nknob4.grid(row=1, column=1)\n                \napp.mainloop() \n```\n![Complex example](https://user-images.githubusercontent.com/89206401/204139428-c3c3c313-539f-4867-9d50-8876a19432ee.png)\n\n## Arguments:\n  | Parameters  | Description |\n  | -------- | ----------- |\n  | _master_ | The master parameter is the parent widget |\n  | _bg_  | The default background color of the knob widget |\n  | _width_ | Define width of the widget manually (optional) |\n  | _height_ | Define height of the widget manually (optional) |\n  | _start_ |  The start point of the range from where the bar will rotate |\n  | _end_ |  The end point of the range |\n  | _radius_ | Define the radius of the knob |\n  | _border_width_ | Define the width of progress bar with respect to the outer and inner ring |\n  | _start_angle_ | Determines the angle from where to rotate |\n  | _text_ | A string that will be displayed on the knob with value |\n  | _text_color_ | Specify the color of the text that will be displayed on the knob |\n  | _text_font_ | Specify the font of the text that will be displayed on the knob |\n  | _integer_ | A boolean (True/False), displays only the integer value in text if True (default=False) |\n  | _fg_ | Specify the color of the inner circle |\n  | _progress_color_ | Define the color of the progress bar |\n  | _bar_color_ | Define the color of the progress bar's background |\n  | _inner_width_ | Define the width of the inner ring |\n  | _inner_color_ | Specify the color of the inner ring |\n  | _outer_width_ | Define the width of the outer ring |\n  | _outer_length_ | Define the distance between progress bar and outer ring |\n  | _inner_color_ | Specify the color of the outer ring |\n  | _steps_ | Number of steps per scroll |\n  | _state_ | Specify the state of the needle |\n  | _command_ | Call a function whenever the bar is moved |\n  \n### Methods:\n  | Methods   | Description |\n  |-----------|-------------|\n  | _.get()_ | get the current value of the knob |\n  | _.set()_ | set the value of the knob |\n  | _.configure()_ | configure parameters of the knob | \n  \n# Meter\n\n## Usage\n**Simple Example**\n```python\nimport tkinter\nfrom tkdial import Meter\n\nroot = tkinter.Tk()\ndial = Meter(root)\ndial.pack(padx=10, pady=10)\n\nroot.mainloop()\n```\n![simple_meter](https://user-images.githubusercontent.com/89206401/204718544-c8589399-7f13-44bb-a07d-77f328ce76b9.png)\n\n### **Different Meter Styles:**\n```python\nimport customtkinter\nfrom tkdial import Meter\n\napp = customtkinter.CTk()\napp.geometry(\"950x350\")\n\nmeter1 = Meter(app, radius=300, start=0, end=160, border_width=0,\n               fg=\"black\", text_color=\"white\", start_angle=270, end_angle=-270,\n               text_font=\"DS-Digital 30\", scale_color=\"white\", needle_color=\"red\")\nmeter1.set_mark(140, 160) # set red marking from 140 to 160\nmeter1.grid(row=0, column=1, padx=20, pady=30)\n\nmeter2 = Meter(app, radius=260, start=0, end=200, border_width=5,\n               fg=\"black\", text_color=\"white\", start_angle=270, end_angle=-360,\n               text_font=\"DS-Digital 30\", scale_color=\"black\", axis_color=\"white\",\n               needle_color=\"white\")\nmeter2.set_mark(1, 100, \"#92d050\")\nmeter2.set_mark(105, 150, \"yellow\")\nmeter2.set_mark(155, 196, \"red\")\nmeter2.set(80) # set value\nmeter2.grid(row=0, column=0, padx=20, pady=30)\n\nmeter3 = Meter(app, fg=\"#242424\", radius=300, start=0, end=50,\n               major_divisions=10, border_width=0, text_color=\"white\",\n               start_angle=0, end_angle=-360, scale_color=\"white\", axis_color=\"cyan\",\n               needle_color=\"white\",  scroll_steps=0.2)\nmeter3.set(15)\nmeter3.grid(row=0, column=2, pady=30)\n\napp.mainloop()\n```\n![styles_meter](https://user-images.githubusercontent.com/89206401/204718389-d3195b3b-0f7a-41c3-85b8-ffc1d961db70.png)\n\n## Arguments:\n  | Parameters  | Description |\n  | -------- | ----------- |\n  | _master_ | The master parameter is the parent widget |\n  | _bg_  | The default background color of the meter widget |\n  | _fg_ | Specify the color of the meter face |\n  | _width_ | Define width of the widget manually (optional) |\n  | _height_ | Define height of the widget manually (optional) |\n  | _start_ |  The start point of the range from where the needle will rotate |\n  | _end_ |  The end point of the range |\n  | _start_angle_ | Determines the starting angle of the arc |\n  | _end_angle_ | Determines the final angle of the arc |\n  | _radius_ | Determines the radius for the widget |\n  | _major_divisions_ | Determines the number of major lines in the scale |\n  | _minor_divisions_ | Determines the number of minor lines in the scale |\n  | _scale_color_ |  Specify the color of the meter scale |\n  | _border_width_ | Define the width of the border case (default=1) |\n  | _border_color_ |  Specify the color of the border case |\n  | _needle_color_ | Specify the color of the needle line |\n  | _axis_color_ | Specify which color of the axis wheel |\n  | _text_ | A string that will be displayed under the meter with value  |\n  | _text_color_ | Specify the color of the text that will be displayed under the meter |\n  | _text_font_ | Specify the font of the text that will be displayed under the meter |\n  | _integer_ | A boolean (True/False), displays only the integer value in text if True (default=False) |\n  | _scroll_ | A boolean (True/False), enables mouse scroll in meter (default=True) |\n  | _scroll_steps_ | Number of steps per scroll |\n  | _state_ | Unbind/Bind the mouse movement with the needle |\n  | _command_ | Call a function whenever the needle is rotated |\n  \n### Methods:\n  | Methods   | Description |\n  |-----------|-------------|\n  | _.get()_ | get the current value of the meter |\n  | _.set()_ | set the value of the meter |\n  | _.configure()_ | configure parameters of the meter| \n  | _.set_mark()_ | set markings for the scale. Eg: **meter.set_mark(from, to, color)** | \n  \n# JogWheel\n\n## Usage\n\n```python\nimport tkinter\nfrom tkdial import Jogwheel\n\napp = tkinter.Tk()\n\nknob = Jogwheel(app)\nknob.grid()\n\napp.mainloop()\n```\n![Jogwheel](https://user-images.githubusercontent.com/89206401/232750598-37f4f863-0aba-48c8-9a69-4cb1e15e1457.png)\n\n### Styles: \n```python\nimport customtkinter\nfrom tkdial import Jogwheel\n\napp = customtkinter.CTk()\n\nwheel_1 = Jogwheel(app, radius=200, fg=\"#045252\", scale_color=\"white\",\n                text=None, button_radius=10)\nwheel_1.set_mark(0,100, \"green\")\n\nwheel_1.grid()\n\nwheel_2 = Jogwheel(app, radius=200, fg=\"#045252\", scale_color=\"white\", start_angle=0,\n                   end_angle=360, start=0, end=200, text=\"Volume: \", button_radius=10)\nwheel_2.set_mark(0,50, \"blue\")\nwheel_2.set_mark(50, 90, \"green\")\nwheel_2.set_mark(90, 150, \"orange\")\nwheel_2.set_mark(150, 200, \"red\")\nwheel_2.grid()\n\napp.mainloop()\n```\n![Jogwheel styles](https://user-images.githubusercontent.com/89206401/232751129-72d29a4e-d0ea-49b4-9051-e65cabd5fb55.png)\n\n\n## Arguments:\n  | Parameters  | Description |\n  | -------- | ----------- |\n  | _master_ | The master parameter is the parent widget |\n  | _bg_  | The default background color of the widget |\n  | _fg_ | Specify the color of the wheel face |\n  | _width_ | Define width of the widget manually (optional) |\n  | _height_ | Define height of the widget manually (optional) |\n  | _start_ |  The start point of the range from where the knob will rotate |\n  | _end_ |  The end point of the range |\n  | _start_angle_ | Determines the starting angle of the arc |\n  | _end_angle_ | Determines the final angle of the arc |\n  | _radius_ | Determines the radius for the widget |\n  | _divisions_ | Determines the number of scale lines in the scale |\n  | _division_height_ | Determines the height of scale lines |\n  | _scale_color_ |  Specify the color of the knob scale |\n  | _border_width_ | Define the width of the border case (default=1) |\n  | _border_color_ |  Specify the color of the border case |\n  | _button_color_ | Specify the color of the knob |\n  | _button_radius_ | Specify the radius the knob |\n  | _text_ | A string that will be displayed with value |\n  | _text_color_ | Specify the color of the text that will be displayed |\n  | _text_font_ | Specify the font of the text that will be displayed |\n  | _integer_ | A boolean (True/False), displays only the integer value in text if True (default=False) |\n  | _scroll_ | A boolean (True/False), enables mouse scroll (default=True) |\n  | _scroll_steps_ | Number of steps per scroll |\n  | _state_ | Unbind/Bind the mouse movement with the widget |\n  | _command_ | Call a function whenever the needle is rotated |\n  \n### Methods:\n  | Methods   | Description |\n  |-----------|-------------|\n  | _.get()_ | get the current value of the knob |\n  | _.set()_ | set the value of the knob |\n  | _.configure()_ | configure parameters of the knob | \n  | _.set_mark()_ | set markings for the scale. Eg: **meter.set_mark(from, to, color)** | \n  \n## ImageKnob\n### Usage\n```python\nimport tkinter\nfrom tkdial import ImageKnob\n\napp = tkinter.Tk()\n\ncustomknob = ImageKnob(app, image=\"knob.png\")\ncustomknob.grid()\n\napp.mainloop()\n```\n\n![customknob](https://user-images.githubusercontent.com/89206401/233058156-007f967e-796c-40f1-9c91-419d990fb725.png)\n\n### Styles:\n```python\n# Note: images are not provided, only for reference\nimport customtkinter\nfrom tkdial import ImageKnob\n\napp = customtkinter.CTk()\n\ncustomknob = ImageKnob(app, image=\"knob.png\", text_color=\"white\", text=\"Volume \")\ncustomknob.grid(row=0, column=0)\n\ncustomknob2 = ImageKnob(app, image=\"knob2.png\", scale_image=\"scale1.png\",text=\"\", scale_width=120)\ncustomknob2.grid(row=0, column=1, padx=20)\n\ncustomknob3 = ImageKnob(app, image=\"knob3.png\", scale_image=\"scale2.png\",text=\"\",\n                        scale_width=50, start_angle=20, end_angle=-240,\n                        progress_color=\"cyan\", progress=True)\ncustomknob3.grid(row=0, column=2)\n\napp.mainloop()\n```\n![customknob styles](https://user-images.githubusercontent.com/89206401/233058217-34888954-89dd-4e30-80ac-98f2d4bba6eb.png)\n\n\n## Arguments:\n  | Parameters  | Description |\n  | -------- | ----------- |\n  | _master_ | The master parameter is the parent widget |\n  | _bg_  | The default background color of the widget |\n  | _width_ | Define width of the widget manually (optional) |\n  | _height_ | Define height of the widget manually (optional) |\n  | _start_ |  The start point of the range from where the knob will rotate |\n  | _end_ |  The end point of the range |\n  | _image_ | pass the knob image |\n  | _scale_image_ | add a scale image (optional) |\n  | _scale_width_ | specify relative distance between scale and knob image |\n  | _start_angle_ | Determines the starting angle of the knob |\n  | _end_angle_ | Determines the final angle of the knob |\n  | _radius_ | Determines the radius for the widget |\n  | _text_ | A string that will be displayed with value |\n  | _text_color_ | Specify the color of the text that will be displayed |\n  | _text_font_ | Specify the font of the text that will be displayed |\n  | _integer_ | A boolean (True/False), displays only the integer value in text if True (default=False) |\n  | _scroll_ | A boolean (True/False), enables mouse scroll (default=True) |\n  | _scroll_steps_ | Number of steps per scroll |\n  | _state_ | Unbind/Bind the mouse movement with the widget |\n  | _command_ | Call a function whenever the needle is rotated |\n  \n### Methods:\n  | Methods   | Description |\n  |-----------|-------------|\n  | _.get()_ | get the current value of the widget |\n  | _.set()_ | set the value of the widget |\n  | _.configure()_ | configure parameters of the widget | \n\nNote: Images should be cropped in fixed ratio (1:1) and saved with transparency(png).\n\n## Conclusion\nThis library is focused to create some circular widgets that can be used with **Tkinter/Customtkinter** easily.\nI hope it will be helpful in UI development with python.\n\n[\u003cimg src=\"https://img.shields.io/badge/LICENSE-CC0_v0.1-informational?\u0026color=blue\u0026style=for-the-badge\" width=\"200\"\u003e](https://github.com/Akascape/TkDial/blob/main/LICENSE)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakascape%2Ftkdial","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fakascape%2Ftkdial","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakascape%2Ftkdial/lists"}