Python Tkinter Tutorial | Skill Web Part 3

preview_player
Показать описание
We complete our dynamic skill web in Python Tkinter by drawing the graphical representation of the skill levels!

Github Code

Skill Web Tutorial | Python Tkinter

Python Tkinter | Project Tutorials

TkDocs

TkDocs | Canvas

TIMESTAMPS
00:00 Intro
00:29 Code
Рекомендации по теме
Комментарии
Автор

FINAL CODE

from tkinter import *
import math
import random

class Root(Tk):
def __init__(self):
super().__init__()
self.title("Skill Web")
self.state("zoomed")

self.skill_web = SkillWeb(self)
self.skill_web.pack(fill=BOTH, expand=1)
self.skill_web.draw()

class SkillWeb(Canvas):
def __init__(self, parent):
super().__init__(parent, bg="#FED6D3")

#Must Have at least 3 Skills!
self.skills = {
"Strength": random.randint(0, 100),
"Intelligence": random.randint(0, 100),
"Willpower": random.randint(0, 100),
"Agility": random.randint(0, 100),
"Speed": random.randint(0, 100),
#"Endurance": random.randint(0, 100),
#"Personality": random.randint(0, 100),
#"Luck": random.randint(0, 100),
}

#Imaginary Circle
self.center_x = self.winfo_width() / 2
self.center_y = self.winfo_height() / 2

#Determines Size of 1st Layer
self.outer_radius = 200

#Determines Size of Last Layer
self.inner_radius = 50

#Number of Layers. Must Be at Least 2!
self.layers = 5

#N-gon (#vertices, skills, edges)
self.n_gon = len(self.skills)

#Vertex Angle
self.vertex_angle = 2 * math.pi / self.n_gon

#Rotates Skill Web
self.offset = (math.pi / 2) * -1

def draw(self):
#Update Canvas
self.update()

#Imaginary Circle Center
self.center_x = self.winfo_width() / 2
self.center_y = self.winfo_height() / 2

#Space Between Each Layer
decrement = (self.outer_radius - self.inner_radius) / (self.layers - 1)

#Skills
skill_names = list(self.skills.keys())

skill_levels = list(self.skills.values())

#Iterate THrough Each Layer
for layer in range(self.layers):
#Calculate Layer Radius
cur_radius = self.outer_radius - layer * decrement

#List to Store Vertices
vertices = []

#Calculate Vertices
for i in range(self.n_gon):
#Calculate Angle for Current Vertex
angle = self.offset + i * self.vertex_angle

#Calculate Vertex Coordinates
x = self.center_x + cur_radius * math.cos(angle)
y = self.center_y + cur_radius * math.sin(angle)

#Append Coordinates to Vertices List
vertices.append([x, y])

#Draw Line Between Vertices for Current Layer
self.create_polygon(vertices, fill="", outline="black", width=3)


#Draw Lines from Center to Outside Vertices
if layer == 0:
for j in range(self.n_gon):
y = vertices[j]

y, self.center_x, self.center_y, width=3)

Skill Names"""

Name Radius
= self.outer_radius + 30

Name Angle
= self.offset + j * self.vertex_angle

Skill Name X, Y
= self.center_x + lbl_r * math.cos(angle)
= self.center_y + lbl_r * math.sin(angle)

Skill Name
lbl_y, text=skill_names[j])

"""Calculate Skill Level Vertices"""

#List to Store Skill Vertices
skill_vertices = []

#Iterate through Skill Levels w/ Index
for l, level in enumerate(skill_levels):
max_level = min(level, 100)

if level == 0:
r = 0

else:
normalized_level = (max_level - 1) / (100 - 1)

r = self.inner_radius + normalized_level * (self.outer_radius - self.inner_radius)

angle = self.offset + l * self.vertex_angle

x = self.center_x + r * math.cos(angle)
y = self.center_y + r * math.sin(angle)

skill_vertices.append([x, y])

#Fill Shape Formed by Skill Vertices
coordinates = [coords for vertex in skill_vertices for coords in vertex]

self.create_polygon(coordinates, fill="#9D8A88", outline="black", width=2)

#Draw Skill Vertices
for x, y in skill_vertices:
self.create_oval(x - 10, y - 10, x + 10, y + 10, fill="#9D8A88", outline="black", width=2)

if ___name___ == "__main__":
root = Root()
root.mainloop()

CodeQuest
join shbcf.ru