我遇到麻烦,字典没有更新其内容,其中一些内容是在定义字典后由循环中的变量定义的。它在第一次运行时读取变量的初始值就好了,但是在用户输入改变变量之后,字典中的数据从不反映这一点。我正在尝试使用curses构建一个菜单系统,该系统将构建和修改另一个python脚本的配置文件。任何帮助将不胜感激。问题在于lightHourConfig
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Topmenu and the submenus are based of the example found at this location http://blog.skeltonnetworks.com/2010/03/python-curses-custom-menu/
# The rest of the work was done by Matthew Bennett and he requests you keep these two mentions when you reuse the code :-)
# Basic code refactoring by Andrew Scheller
from time import sleep
import curses, os #curses is the interface for capturing key presses on the menu, os launches the files
screen = curses.initscr() #initializes a new window for capturing key presses
curses.noecho() # Disables automatic echoing of key presses (prevents program from input each key twice)
#curses.cbreak() # Disables line buffering (runs each key as it is pressed rather than waiting for the return key to pressed)
curses.start_color() # Lets you use colors when highlighting selected menu option
screen.keypad(1) # Capture input from keypad
# Change this to use different colors when highlighting
curses.init_pair(1,curses.COLOR_BLACK, curses.COLOR_WHITE) # Sets up color pair #1, it does black text with white background
curses.init_pair(2,curses.COLOR_GREEN, curses.COLOR_BLACK)
curses.init_pair(3,curses.COLOR_RED, curses.COLOR_BLACK)
h = curses.color_pair(1) #h is the coloring for a highlighted menu option
n = curses.A_NORMAL #n is the coloring for a non highlighted menu option
MENU = "menu"
COMMAND = "command"
INPUT = "input"
EXITMENU = "exitmenu"
######Variables Default if no File######
lightCycleConfigID = 1
lightHourConfig = 21
########Variables Pulled by File########
#####Convert Vars need as strings#######
if lightCycleConfigID == 1:
lightCycleConfig = "24/0"
menu_data = {
'title': "GCB Main Menu", 'lightHourMenuSetting': lightHourConfig, 'type': MENU, 'subtitle': "Please select an option...",
'options':[
{ 'title': "Light Configuration", 'type': MENU, 'subtitle': 'Light Configuration Setup',
'options': [
{ 'title': "Light Cycle Current Setting: "+lightCycleConfig, 'type': MENU, 'subtitle': 'Select a Light Cycle...',
'options': [
{ 'title': "24/0 | Clones/Veg", 'type': COMMAND, 'command': '' },
{ 'title': "18/6 | Mid/Late Veg", 'type': COMMAND, 'command': '' },
{ 'title': "16/8 | Mid/Late Veg", 'type': COMMAND, 'command': '' },
{ 'title': "14/10 | Flowering", 'type': COMMAND, 'command': '' },
{ 'title': "12/12 | Flowering", 'type': COMMAND, 'command': '' },
]
},
{ 'title': "Lights ON Time Current Setting: "+str(lightHourConfig)+":00", 'type': INPUT, 'textdisp': 'Enter the hour for Lights ON start, Local Time 0-23: ', 'id': 1 },
]
},
{ 'title': "Fan Configuration", 'type': MENU, 'subtitle': 'Fan Configuration Setup',
'options': [
{ 'title': "High Temp Activation", 'type': COMMAND, 'command': '' },
{ 'title': "Exhaust Cycle Time", 'type': COMMAND, 'command': '' },
]
},
{ 'title': "Modules Setup", 'type': COMMAND, 'command': '' },
{ 'title': "API Keys", 'type': MENU, 'subtitle': "Select Service to edit API Key",
'options': [
{ 'title': "Xively", 'type': COMMAND, 'command': '' },
{ 'title': "Prowl", 'type': COMMAND, 'command': '' },
]
},
{ 'title': "MENU", 'type': COMMAND, 'command': '' },
{ 'title': "ITEM", 'type': COMMAND, 'command': '' },
]
}
# This function displays the appropriate menu and returns the option selected
def runmenu(menu, parent):
# work out what text to display as the last menu option
if parent is None:
lastoption = "Exit"
else:
lastoption = "Return to %s" % parent['title']
optioncount = len(menu['options']) # how many options in this menu
pos=0 #pos is the zero-based index of the hightlighted menu option. Every time runmenu is called, position returns to 0, when runmenu ends the position is returned and tells the program what opt$
oldpos=None # used to prevent the screen being redrawn every time
x = None #control for while loop, let's you scroll through options until return key is pressed then returns pos to program
# Loop until return key is pressed
while x !=ord('\n'):
if pos != oldpos:
oldpos = pos
screen.border(0)
screen.addstr(2,2, menu['title'], curses.color_pair(2)) # Title for this menu
screen.addstr(4,2, menu['subtitle'], curses.A_BOLD) #Subtitle for this menu
# Display all the menu items, showing the 'pos' item highlighted
for index in range(optioncount):
textstyle = n
if pos==index:
textstyle = h
screen.addstr(5+index,4, "%d - %s" % (index+1, menu['options'][index]['title']), textstyle)
# Now display Exit/Return at bottom of menu
textstyle = n
if pos==optioncount:
textstyle = h
screen.addstr(5+optioncount,4, "%d - %s" % (optioncount+1, lastoption), textstyle)
screen.refresh()
# finished updating screen
x = screen.getch() # Gets user input
# What is user input?
if x >= ord('1') and x <= ord(str(optioncount+1)):
pos = x - ord('0') - 1 # convert keypress back to a number, then subtract 1 to get index
elif x == 258: # down arrow
if pos < optioncount:
pos += 1
else: pos = 0
elif x == 259: # up arrow
if pos > 0:
pos += -1
else: pos = optioncount
# return index of the selected item
return pos
# This function calls showmenu and then acts on the selected item
def processmenu(menu, parent=None):
optioncount = len(menu['options'])
exitmenu = False
while not exitmenu: #Loop until the user exits the menu
getin = runmenu(menu, parent)
if getin == optioncount:
exitmenu = True
elif menu['options'][getin]['type'] == COMMAND:
#curses.def_prog_mode() # save curent curses environment
if menu['options'][getin]['title'] == 'Pianobar':
os.system('amixer cset numid=3 1') # Sets audio output on the pi to 3.5mm headphone jack
screen.clear() #clears previous screen
os.system(menu['options'][getin]['command']) # run the command
screen.clear() #clears previous screen on key press and updates display based on pos
curses.reset_prog_mode() # reset to 'current' curses environment
curses.curs_set(1) # reset doesn't do this right
curses.curs_set(0)
elif menu['options'][getin]['type'] == MENU:
screen.clear() #clears previous screen on key press and updates display based on pos
processmenu(menu['options'][getin], menu) # display the submenu
screen.clear() #clears previous screen on key press and updates display based on pos
elif menu['options'][getin]['type'] == INPUT and menu['options'][getin]['id'] == 1:
screen.clear()
screen.border(0)
screen.addstr(4,2, menu['options'][getin]['textdisp'], curses.color_pair(2)) #Subtitle for this menu
while True:
lightHourConfig = 0
try:
curses.echo()
lightStart = int(screen.getstr(6, 3))
curses.noecho()
if lightStart < 24:
lightHourConfig = lightStart
#need to insert code to write value to config file
break
else:
raise ValueError()
except ValueError:
screen.addstr(5,2, "Invalid Input. 0-23 Only!", curses.color_pair(3))
screen.move(6, 2)
screen.clrtoeol()
screen.border(0)
screen.clear()
elif menu['options'][getin]['type'] == EXITMENU:
exitmenu = True
# Main program
processmenu(menu_data)
curses.endwin() #VITAL! This closes out the menu system and returns you to the bash prompt.
os.system('cls')
答案 0 :(得分:0)
创建dict时,它会将lightHourConfig中包含的数字,而不是变量&#34; lightHourConfig&#34;,分配给键。所以它永远不会改变。有几种方法可以改变它: 您可以直接更新它:
menu_data['lightHourConfig'] = 20
但是你必须为它出现的每个地方都这样做。 另一种方法是将lightHourConfig初始化为dict:
lightHourConfig = {"value" : 24}
然后当你改变这样的值时,在其他地方:
lightHourConfig["value"] = 20
它将在其他地方更新,因为现在menu_data实际上将存储对lightHourConfig的引用,而不仅仅是其中的文字数据。当然,这样做会对菜单数据的显示方式产生其他影响。