2014-01-26 3 views
0

Я использую Python для представления иерархии меню на малине Pi для временной съемки. Я использую 2-строчный x 16-цветной ЖК-дисплей и четыре кнопки < (перейдите в родительское меню),^(перейдите к предыдущему брату), v (перейдите к следующему брату) &> (выберите - т.е. перейдите к первому ребенку).Меню Python с использованием связанных объектов

Это моя первая игра с Python, так что есть куча вещей, о которых я еще не знаю. До сих пор я определил класс menuItem со способами добавления и получения имени, родительского элемента и множества других вещей. Моя трудность заключается в том, чтобы узнать, как получить набор дочерних элементов menuItems (self.getChildren) или получить элементы меню sibling (self.getSiblings), чтобы я мог получить следующих и предыдущих братьев и сестер в иерархии. Я понимаю, что иерархия подразумевается только порядком создания и методом setParent.

Я искал и увидел, что может быть множество способов решить эту проблему, например chainMaps? или класс меню - без сомнения, есть больше способов. Может ли кто-нибудь помочь мне выбрать эффективный и понятный метод. (Помните, я новичок в этом, так что «легко понять» лучше для меня, по крайней мере, чем лаконичной изысканности и сложности)

Мой код до сих пор (будь добр: о)

##################################################################### 
# A menuItem chains to other menuItems 
##################################################################### 
class MenuItem: 
    def __init__(self): 
     self.children = '' 

    #setName: method to give a name to this menu item 
    def setName(self, name): 
     self.name = name 

    #getName: method to report the name of this menu item 
    def getName(self): 
     return self.name 

    #setParent: method to set the parent menu item for this menu item 
    def setParent(self, parent): 
     self.parent = parent 

    #getParent: method to report the parent menu item for this menu item 
    def getParent(self): 
     return self.parent 

    #setPrevious: method to set the previous sibling menu item 
# def setPrevious(self, previous): 
#  self.previous = previous 

    #getPrevious: method to report the previous sibling menu item 
    def getPreviousSibling(self): 
     return self.previousSibling 

    #setNext: method to set the next sibling menu item 
# def setNext(self, nxt): 
#  self.nxt = nxt 

    #getNext: method to report the next sibling menu item 
    def getNextSibling(self): 
     return self.nextSibling 

    #setChildren: method to append a new child menuItem 
    # to be called from the point of instantiating the child menuItem 
    def setChildren(self, appendMenuItem): 
     self.children = self.children + ',' + appendMenuItem 

    #getChildren: method to report the list of children manu items 
    def getChildren(self): 
     return self.children 

    #getSiblings: method to report the sibling menu items 
    def getSiblings(self): 
     return self.siblings 

    #setDisplayString: method to set the string that will be displayed on the LCD (max 16 characters) 
    def setDisplayStringL1(self, displayStringL1): 
     self.displayStringL1 = displayStringL1 

    #setDisplayString: method to set the string that will be displayed on the LCD (max 16 characters) 
    def setDisplayStringL2(self, displayStringL2): 
     self.displayStringL2 = displayStringL2 

    #getDisplayStringL1: method to report the first string that is displayed on the LCD for this menu item 
    def getDisplayStringL1(self): 
     return self.displayStringL1 

    #getDisplayStringL2: method to report the second string that is displayed on the LCD for this menu item 
    def getDisplayStringL2(self): 
     return self.displayStringL2 

    #setValidValues: method to set valid values (comma delimited)(need to think about how to do ranges or positive integers) 
    def setValidValues(self, validValues): 
     self.validValues = validValues 

    #stringUpdateChars: method to update a section of the display string 
    def stringUpdateChars(self,LineNum, startChar, endChar, ValString): 
     if LineNum == 1: 
      for i in range (0,(endChar-startChar),1): #there must be a better way to do this! 
       self.displayStringL1[startChar+i] = ValString[i] 
     elif LineNum == 2: 
      for i in range (0,(endChar-startChar),1): 
       self.displayStringL2[startChar+i] = ValString[i] 


def InitialiseMenu(): 
    menuitem1 = MenuItem() 
    menuitem1.setName('applications') 
    menuitem1.setDisplayStringL1('Applications') 
    menuitem1.setDisplayStringL2('') 
    menuitem1.setParent('none') 

    menuitem2 = MenuItem() 
    menuitem2.setName('timeLapse') 
    menuitem2.setDisplayStringL1('Time Lapse') 
    menuitem2.setDisplayStringL2('') 
    menuitem2.setParent(menuitem1) 

    menuitem3 = MenuItem() 
    menuitem3.setName('bulb') 
    menuitem3.setDisplayStringL1("Man. Set 'bulb'") 
    menuitem3.setDisplayStringL2('') 
    menuitem3.setParent(menuitem2) 

    menuitem4 = MenuItem() 
    menuitem4.setName('exposure') 
    menuitem4.setDisplayStringL1("Exp:00 s") 
    menuitem4.setDisplayStringL2("E00s") 
    menuitem4.setValidValues(1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,35,40,45,50,60) 
    menuitem4.setParent(menuitem3) 

    menuitem5 = MenuItem() 
    menuitem5.setName('expUnits') 
    menuitem5.setDisplayStringL1("Exp:00 s") 
    menuitem5.setDisplayStringL2("E00s") 
    menuitem5.setValidValues('s','m') 
    menuitem5.setParent(menuitem4) 

    menuitem6 = MenuItem() 
    menuitem6.setName('delay') 
    menuitem6.setDisplayStringL1("Delay:00 s") 
    menuitem6.setDisplayStringL2("E00s D00s") 
    menuitem6.setValidValues(1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,35,40,45,50,60) 
    menuitem6.setParent(menuitem5) 

    menuitem7 = MenuItem() 
    menuitem7.setName('delayUnits') 
    menuitem7.setDisplayStringL1("Delay:00 s") 
    menuitem7.setDisplayStringL2("E00s D00s") 
    menuitem7.setValidValues('s','m') 
    menuitem7.setParent(menuitem6) 

    menuitem8 = MenuItem() 
    menuitem8.setName('frames') 
    menuitem8.setDisplayStringL1("Frames:00000") 
    menuitem8.setDisplayStringL2("E00s D00s F0000") 
    menuitem8.setParent(menuitem7) 

    #--------------------------  

    menuitem9 = MenuItem() 
    menuitem9.setName('clipLength') 
    menuitem9.setDisplayStringL1("Clip length") 
    menuitem9.setDisplayStringL2('') 
    menuitem9.setParent(menuitem2) 

    menuitem10 = MenuItem() 
    menuitem10.setName('clipLengthPeriod') 
    menuitem10.getDisplayStringL1("Len:00 s") 
    menuitem10.getDisplayStringL2("L:00s") 
    menuitem10.setParent(menuitem9) 

    menuitem11 = MenuItem() 
    menuitem11.setName('clipLengthPeriodUnits') 
    menuitem11.getDisplayStringL1("Len:00 s") 
    menuitem11.getDisplayStringL2("L:00s") 
    menuitem11.setParent(menuitem10) 

    menuitem12 = MenuItem() 
    menuitem12.setName('fps') 
    menuitem12.getDisplayStringL1("FPS:00/s") 
    menuitem12.getDisplayStringL2("F:00s fps:00") 
    menuitem12.setValidValues(20,21,22,23,24,25,26,27,28,29,30) 
    menuitem12.setParent(menuitem11)  

    #--------------------------  
    menuitem13 = MenuItem() 
    menuitem13.setName('realTime') 
    menuitem13.getDisplayStringL1("Real-time") 
    menuitem13.setDisplayStringL2('') 
    menuitem13.setParent(menuitem2) 

    menuitem14 = MenuItem() 
    menuitem14.setName('realTimePeriod') 
    menuitem14.getDisplayStringL1("Per:00 s") 
    menuitem14.getDisplayStringL2("P:00s") 
    menuitem14.setParent(menuitem13) 

    menuitem15 = MenuItem() 
    menuitem15.setName('realTimePerioddUnits') 
    menuitem15.getDisplayStringL1("Per:00 s") 
    menuitem15.getDisplayStringL2("P:00s") 
    menuitem15.setParent(menuitem14) 

    menuitem16 = MenuItem() 
    menuitem16.setName('realTimefps') 
    menuitem16.getDisplayStringL1("FPS:00/s") 
    menuitem16.getDisplayStringL2("f:00s fps:00") 
    menuitem16.setValidValues(20,21,22,23,24,25,26,27,28,29,30) 
    menuitem16.setParent(menuitem15)  

    menuitem16 = MenuItem() 
    menuitem16.setName('startPauseStop') 
    menuitem16.setDisplayStringL1("Start") 
    menuitem16.setDisplayStringL2("press > to start") 
    menuitem16.setParent(menuitem2)  

userInput = 'yes' 
#when the other navigation is enabled, I'll set this to menuItem1 
currentMenuItem = menuitem8 #<-this is in error - indent problem? 
#type 'no' to exit or use <|^|v|> to navigate 
#I'm expecting this to keep asking for input. Each time < is pressed it'll print out the name of the parent menuItem up to the root item 
while userInput != "no": 
    userInput = raw_input("<^v > ") 
    #up tree 
    if userInput == "<": 
     if currentMenuItem.getParent().getName() != "none": 
      currentMenuItem = currentMenuItem.getParent() 
      print "current menu item: " + currentMenuItem.getName() 
     else: 
      print "current menu item: " + currentMenuItem.getName() 
#  #previous sibling 
#  elif userInput == "^": 
#   if currentMenuItem.getParent() != "none": 
#    currentMenuItem = currentMenuItem.getParent() 
#    print currentMenuItem.getName() 
#  #next sibling 
#  elif userInput == "v": 
#   if currentMenuItem.getParent() != "none": 
#    currentMenuItem = currentMenuItem.getParent() 
#    print currentMenuItem.getName() 
#  #select - first child 
#  elif userInput == ">": 
#   if currentMenuItem.getParent() != "none": 
#    currentMenuItem = currentMenuItem.getParent() 
#    print currentMenuItem.getName() 
print "Finished!" 

ответ

1

One способ сделать это будет атрибутом класса проведения всех MenuItem экземпляров, а затем с помощью клавиш для этого словаря, имена элементов, чтобы перемещаться между ними:

class MenuItem(object): 

    items = {} 

    def __init__(self, name, parent): 
     self.name = name 
     self._parent = parent 
     MenuItem.items[name] = self  

    @property 
    def parent(self): 
     return MenuItem.items[self._parent] 

    @parent.setter 
    def set_parent(self, parent): 
     if parent in MenuItem.items: 
      self._parent = parent 
     else: 
      raise ValueError 

Обратите внимание на использование property, более Pythonic чем get и set.

+0

Почему это не является self._name = имя так же, как и self._parent = parent? – Greg

+0

'name' не нуждается в обработке, чтобы получить или установить, поэтому вы получаете доступ к ней напрямую. 'parent' нуждается в обработке, поэтому я устанавливаю атрибут private-by-convention' _parent' для хранения значения, доступного по свойству 'parent' – jonrsharpe

Смежные вопросы