我绝对建议创建一个类Item,即使您只有text和function属性!
谁知道你以后需要什么样的复杂逻辑。
考虑到这一点,创建菜单可能看起来像这样:main = Menu()
main.AddItem(Item("Open", openFile))
main.AddItem(Item("Close", closeFile))
另外,在text和function属性之上,应该将parent属性添加到Item类。parent只需指向项目的父菜单:main = Menu()
# automatically calls main.AddItem(item1)
open = Item("Open", openFile, main)
# automatically sets parent to main
main.Add(Item("Close", closeFile))
既然我们知道了正确的Menu和Item应该如何工作,我们就可以开始编写类了。
菜单
这不应该太难,我们只需要add_item()、remove_item()和draw()方法以及items列表。
另外,最好绘制菜单的名称,所以让我们添加name属性。class Menu:
def __init__(self, name, items=None):
self.name = name
self.items = items or []
def add_item(self, item):
self.items.append(item)
if item.parent != self:
item.parent = self
def remove_item(self, item):
self.items.remove(item)
if item.parent == self:
item.parent = None
def draw(self):
print(self.label)
for item in self.items:
item.draw()
显然,我们可以为菜单编写更多的方法和属性,但这包括所有的基本方法。
项目
Item类应该更简单,它根本不需要任何方法。
显然,Item需要一个name和一个function(函数将在Item被激活时运行),除此之外,它还有前面提到的parent属性。
我们可能应该为parent创建一个setter,它将自动移动另一个菜单下的项,但如果您想这样做,我将留给您。
另外,也不要忘记item的draw()-方法,我们必须能够按照它们想要的方式绘制它们,而不是按照我们的Menu想要的方式绘制它们。class Item:
def __init__(self, name, function, parent=None):
self.name = name
self.function = function
self.parent = parent
if parent:
parent.add_item(self) # use add_item instead of append, since who
# knows what kind of complex code you'll have
# in add_item() later on.
def draw(self):
# might be more complex later, better use a method.
print(" " + self.name)
最终想法
我们现在已经完成了菜单,它的工作,你应该可以使用它作为一个基本的菜单。
但是,高级控制台菜单只有一个名为MenuItem的类。
每个项的父项都是另一个MenuItem(当然是每个,但是根MenuItem)菜单在绘制时看起来像这样:[-] Root
[+] Submenu of Root
[-] An other submenu of Root
This menu runs functions, others open/close
Select this menu by pressing mousedown
[+] A third submenu of Root
不提供function参数将创建items列表并允许用户关闭/打开菜单项。
如果给定function,它将正常工作,并且仅在选中时执行函数。
更进一步,我们将分离MenuItem和两个子类:ActionMenu和ContainerMenu。
但请记住,这是有点难以编码,不适合初学者。你可能想坚持我经历的第一个版本。