我有一个名为Bone
的类,其属性为(与在此问题中如何实现无关):
称为BoneFrame
的类实际上创建了一个这样的框架(我也不认为如何实现):
在主脚本中,我有一个名为categories
的变量,它具有2级类别。主要类别,然后是子类别。例如,二头肌是主类别Upper body
的一部分,并且是子类别Arms
的一部分。
我想知道如何根据所选的主要类别/子类别过滤出帧。因此,仅显示相关的帧。在下面的图片中,选择了主要类别Upper body
。然后子类别会更新(并显示上半身子类别的列表),在这种情况下,将选择Arms
子类别。
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()
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)
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
答案 0 :(得分:1)
基本上,您正在寻找两个Listbox
小部件,它们会根据用户的选择做出反应。为此,您可以绑定到"<<ListboxSelect>>"
事件,然后填充下一个Listbox
或BoneFrame
。在下面,我删除了Bone
和BoneFrame
类中的所有方法,以使代码最少:
import tkinter as tk
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
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)
}
class BoneFrame(tk.Frame):
def __init__(self,master=None, bone=None, **kwargs):
super().__init__(master, kwargs)
for num, i in enumerate((bone.name, bone.w, bone.x, bone.y, bone.z)):
tk.Label(self,text=i).grid(row=0,column=num)
class BoneGUI(tk.Tk):
def __init__(self):
super().__init__()
self.categories = {
"Upper Body": {
"Arms": [BoneFrame(self,skeleton.get(1)),
BoneFrame(self,skeleton.get(3))],
"Chest": [BoneFrame(self,skeleton.get(2))]
},
"Lower Body": {
"Legs": [BoneFrame(self,skeleton.get(6))],
"Foot": [BoneFrame(self,skeleton.get(4)),
BoneFrame(self, skeleton.get(5))]
}
}
self.current_selection = None
self.showing = []
self.part = None
self.main_cat = tk.Listbox(self,height=3,exportselection=False)
for i in list(self.categories.keys()):
self.main_cat.insert(tk.END,i)
self.main_cat.grid(row=0,column=0,rowspan=2)
self.sub_cat = tk.Listbox(self,height=3,exportselection=False)
self.sub_cat.grid(row=0,column=1,rowspan=2)
self.main_cat.bind("<<ListboxSelect>>", self.populate_sub_cat)
self.sub_cat.bind("<<ListboxSelect>>", self.populate_frame)
def populate_sub_cat(self, event=None):
self.sub_cat.delete(0, "end")
self.current_selection = self.categories.get(self.main_cat.get(self.main_cat.curselection()))
for x in self.current_selection:
self.sub_cat.insert(tk.END, x)
def populate_frame(self, event=None):
for i in self.showing:
i.grid_forget()
self.part = self.sub_cat.get(self.sub_cat.curselection())
for num, frame in enumerate(self.current_selection.get(self.part)):
frame.grid(row=num,column=2)
self.showing.append(frame)
root = BoneGUI()
root.mainloop()