2013-02-26 47 views
3

正如標題所說,我正在用Python編寫一個控制檯菜單生成器。我有2個課程,菜單和項目。但我陷入困境。下面是代碼:Python中的控制檯菜單生成器

class Menu: 
    def AddItem(self,item): 
     class Item: 
      def __init__(self,text,ToDoNext): 
       self.text=text 
       ?????????????? 
     self.item.append(Item()) 
    def Show(): 
     for i in range(len(self.item)): 
      print(str(i+1)+") "+str(self.item[i])+"\n") 
     print("0) Back\n") 
     option=int(input()) 
     self.item[option].???????????? 

此代碼基本上做到了下:

Main=Menu() 
Menu.AddItem("Open file",ToDo1) 
Menu.AddItem("Save file",ToDo2) 
Menu.Show() 

'''1) Open file 
    2) Save file 
    0) Back 
    _ 
''' 

如果我寫1,然後按回車應該做的代碼ToDo1的部分,例如。 ,我認爲該解決方案是nextone:

def ToDo1(): 
    print("Hello, world!") 
Menu.AddItem("Say Hello","ToDo1()") 

,並使用Show()內的eval()功能。

但我不敢肯定這不是做這件事的正確方法。

我想讓你給我一個更好的方法,如果你曾經做過類似的事情(控制檯菜單生成器)來分享代碼,並看到另一種方式做同樣的事情。

回答

0

函數可以在Python中自由傳遞。如果你說AddItem("Say Hello", ToDo1),你傳遞值ToDo1,這是一個函數對象。然後,您可以將其存儲在self.function中,稍後用fn = self.item[option].function進行釣魚,然後用fn()與之聯繫。當你意識到像do_stuff()這樣的常規函數​​調用實際上是兩件事情時,它更清晰:首先從變量do_stuff(通常是永不改變的全局變量)獲取函數對象,然後調用該函數對象。

0

這裏是一個工作示例

通常類菜單部分將是所謂的「MYMENU」和進口與命令from myMenu import myMenu

項另一個文件是字典的陣列。每個列表項有兩個條目,「文本」和「功能」

爲數組爲零

import sys 
class myMenu: 
    items=[] 

    def AddItem(self,text,function): 
     self.items.append({'text': text, 'func':function}) 

    def Show(self): 
     c=1 
     for l in self.items: 
      print c, l['text'],"\n" 
      c = c +1 

    def Do(self,n): 
     self.items[n]['func']() 

def clist(): 
    print "cheeses are wensleydale and cheddar\n" 

def bye(): 
    print "bye" 
    sys.exit(0) 

if __name__ == "__main__": 
    m=myMenu() 
    m.AddItem("cheese",clist) 
    m.AddItem("quit",bye) 

while(True): 
    m.Show() 
    n=input("choice>") 
    m.Do(n-1) 

開始如果你想有菜單項的輸入被稱爲N-1的字典一類,而不是一本字典,然後立即聲明類類的MyMenu後,所以像這樣(未測試)

class myMenu: 
    items=[] 
    class Item: 
     func=None 
     text="default" 

     def __init__(self,t,f): 
      self.text=t 
      self.func=f 

    def AddItem(self,text,function): 
     self.items.append(Item(text,function)) 
6

我絕對建議創建一個類Item,即使你只有textfunction屬性!誰知道你以後需要什麼樣的複雜邏輯。 考慮到這一點,造就了菜單可能會是這個樣子:

main = Menu() 
main.AddItem(Item("Open", openFile)) 
main.AddItem(Item("Close", closeFile)) 

此外,您textfunction屬性之上,你應該添加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)) 

現在我們知道如何適當MenuItem應該工作,我們就可以開始編寫類。


菜單

這應該不是太難,我們需要的是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() 

顯然,我們可以編寫更多的方法和我們的菜單屬性,但包括所有必要的方法。


項目

項目類應該是更容易,它幾乎不需要任何方法都沒有。 該項目顯然需要一個name和一個function(函數將在物件被激活時運行),最重要的是它具有前面提到的parent屬性。 我們可能應該爲parent創建一個setter,它會自動將該項目移動到其他菜單下,但如果您想要這樣做,我會爲您保留該項目。 也不要忘記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 
     <This menu has focus on it> 
      Select this menu by pressing mousedown 
    [+] A third submenu of Root 

如果不給function參數將創建items列表允許用戶關閉/打開菜單項。 如果給出function,它將正常工作,並且只在選擇時才執行該功能。爲了更進一步,我們將分開MenuItem和兩個子類:ActionMenuContainerMenu。 但請記住,這是有點難以編碼,不適合初學者。你可能想堅持我經歷的第一個版本。

+0

有人真的花了一些時間在菜單上工作?這給了我很多新的信息,完全得到了我的讚賞! – 2013-02-26 10:02:59