У меня есть класс с именем Bone
, который имеет атрибуты (не имеет значения, как это реализовано в этом вопросе):
- id
- name
- w (w - позиция)
- x (x - позиция)
- y (y - позиция)
- z (z - позиция)
Класс с именем BoneFrame
, который, по сути, создает подобный фрейм (я не думаю, что это имеет значение, как это реализовано):

В основном скрипте у меня есть переменная с именем categories
, которая имеет 2 уровня категорий. Основная категория, затем подкатегория. Например, бицепс является частью основной категории Upper body
и в подкатегории Arms
.
Мне было интересно, как я могу отфильтровать кадры на основе основной категории / подэлементакатегория выбрана. Таким образом, отображаются только соответствующие кадры. На картинке ниже выбрана основная категория Upper body
. Затем подкатегории обновляются (и показывают список подкатегорий верхней части тела), и в этом случае выбирается подкатегория Arms
.

Main.py
from tkinter import *
from tkinter import ttk
from Bone import *
from BoneFrame import *
root = Tk()
root.geometry('500x500')
boneFrame = Frame(root, bg="cyan")
boneFrame.grid(row=0, column=0, sticky=W)
# Dictonary of bone objects
skeleton = {
1: Bone(1, "Bicep", 0, 0, 0, 1),
2: Bone(2, "Mid Chest", -0.705721, 0.0035173, 0.0442479, 0.707098),
3: Bone(3, "Forarm", -0.0029335, -0.0260022, 0.6981489, 0.7154743),
4: Bone(4, "Feet", 0.0189131, -0.0307881, -0.0195522, 0.9991557),
5: Bone(5, "Toes", 0.0222693, 0.396756, 0.0086796, 0.9176129),
6: Bone(6, "Thigh", 0.0089054, 0.3955458, 0.0229391, 0.9181166)
}
# Dictionary of Tkinter frames with a reference to the
# Bone object
boneFrames = {}
for bone_id, bone in skeleton.items():
boneFrames[bone_id] = BoneFrame(boneFrame, bone)
# If you uncomment the line below, you'll see it makes
# 6 frames for the 6 bones
boneFrames[bone_id].pack()
people = {
"Upper Body": {
"Arms": [boneFrames[1], boneFrames[3]],
"Chest": [boneFrames[2]]
},
"Lower Body": {
"Legs": [boneFrames[6]],
"Foot": [boneFrames[4], boneFrames[5]]
}
}
root.wm_attributes("-topmost", 1)
root.mainloop()
BoneFrame.py
from tkinter import *
from tkinter import ttk
from Bone import *
ID_WIDTH = 5
ID_PADDING = 15
VAL_PADDING = 2
PLUS_PADDING = 10
class BoneFrame(Frame):
def __init__(self, parent, bone):
super().__init__(parent)
self.bone = bone
self.name = Label(self, text=self.bone.get_name(), width=10)
self.name.grid(row=0, column=0, sticky=W)
# W Positon
self.w_var = StringVar()
self.w_var.set(self.bone.w)
self.w_val = Label(self, textvariable=self.w_var, width=7)
self.w_plus_btn = Button(self, text="+", command= lambda: self.incr_w())
self.w_minus_btn = Button(self, text="-", command= lambda: self.decr_w())
self.w_plus_btn.grid(row=0, column=1)
self.w_val.grid(row=0, column=2, sticky=W, padx=(VAL_PADDING, VAL_PADDING))
self.w_minus_btn.grid(row=0, column=3)
# X Position
self.x_var = StringVar()
self.x_var.set(self.bone.x)
self.x_val = Label(self, textvariable=self.x_var, width=7)
self.x_plus_btn = Button(self, text="+", command= lambda: self.incr_x())
self.x_minus_btn = Button(self, text="-", command= lambda: self.decr_x())
self.x_plus_btn.grid(row=0, column=4, padx=(PLUS_PADDING, 0))
self.x_val.grid(row=0, column=5, sticky=W, padx=(VAL_PADDING, VAL_PADDING))
self.x_minus_btn.grid(row=0, column=6)
# Y Positon
self.y_var = StringVar()
self.y_var.set(self.bone.y)
self.y_val = Label(self, textvariable=self.y_var, width=7)
self.y_plus_btn = Button(self, text="+", command= lambda: self.incr_y())
self.y_minus_btn = Button(self, text="-", command= lambda: self.decr_y())
self.y_plus_btn.grid(row=0, column=7, padx=(PLUS_PADDING, 0))
self.y_val.grid(row=0, column=8, sticky=W, padx=(VAL_PADDING, VAL_PADDING))
self.y_minus_btn.grid(row=0, column=9)
# Z Positon
self.z_var = StringVar()
self.z_var.set(self.bone.z)
self.z_val = Label(self, textvariable=self.z_var, width=7)
self.z_plus_btn = Button(self, text="+", command= lambda: self.incr_z())
self.z_minus_btn = Button(self, text="-", command= lambda: self.decr_z())
self.z_plus_btn.grid(row=0, column=10, padx=(PLUS_PADDING, 0))
self.z_val.grid(row=0, column=11, sticky=W, padx=(VAL_PADDING, VAL_PADDING))
self.z_minus_btn.grid(row=0, column=12)
def incr_w(self):
self.bone.incr_w()
self.w_var.set(self.bone.w)
def decr_w(self):
self.bone.decr_w()
self.w_var.set(self.bone.w)
def incr_x(self):
self.bone.incr_x()
self.x_var.set(self.bone.x)
def decr_x(self):
self.bone.decr_x()
self.x_var.set(self.bone.x)
def incr_y(self):
self.bone.incr_y()
self.y_var.set(self.bone.y)
def decr_y(self):
self.bone.decr_y()
self.y_var.set(self.bone.y)
def incr_z(self):
self.bone.incr_z()
self.z_var.set(self.bone.z)
def decr_z(self):
self.bone.decr_z()
self.z_var.set(self.bone.z)
Bone.py
INCREMENT = 0.01
class Bone:
def __init__(self, boneId, name, w, x, y, z):
self.id = boneId
self.name = name
self.w = w
self.x = x
self.y = y
self.z = z
def get_id(self):
return self.id
def positive_incr(self, num):
newVal = round(num + INCREMENT, 2)
if (newVal > 1):
return 1
return newVal
def negative_incr(self, num):
newVal = round(num - INCREMENT, 2)
if (newVal < -1):
return -1
return newVal
def incr_w(self):
self.w = self.positive_incr(self.w)
self.update_imvu_pos("inf0.33,0.324,0.23")
def decr_w(self):
self.w = self.negative_incr(self.w)
def incr_x(self):
self.x = self.positive_incr(self.x)
def decr_x(self):
self.x = self.negative_incr(self.x)
def incr_y(self):
self.y = self.positive_incr(self.y)
def decr_y(self):
self.y = self.negative_incr(self.y)
def incr_z(self):
self.z = self.positive_incr(self.z)
def decr_z(self):
self.z = self.negative_incr(self.z)
def get_name(self):
return self.name