-
Notifications
You must be signed in to change notification settings - Fork 145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Advise on python data #757
Comments
Hi! First, you might find these threads and the associated documentation helpful (the first two links are discussion about creating the class documented at the last one):
It sounds like your use-case might be a good candidate for the More generically, the data structure I would suggest for storing such menu items is a list, where each item is a class instance. You might define a class like so (fields are just guesses based on your description): class MenuItem:
def __init__(self, menu, line, name, program):
self.menu = menu
self.line = line
# etc... And then you'd define your menu items similar to this: menu_items = [
MenuItem(5, 10, "foo", "foo.py"),
MenuItem(10, 3, "bar", "bar.py"),
] You would then also store the index of the currently-focused item. When up is pressed, you decrement the index; when down is pressed, you increment it. Then re-draw the menu with the new item highlighted. Does that help? |
This is EXACTLY what I was looking for. I found a few articles on this construct, but they were overly complicated and hard to understand. One last question... Once the menu_items object is built, how do I access it? |
this is what I came up with (untested). Am I on the right track? ( i don't know how to format the below code so it appears correct... sorry :( ) class MenuItem:
def __init__(self, menu, line,linename, linetype, lineprog):
self.menu = menu
self.line = line
self.linename = linename
self.linetype = linetype
self.lineprog = lineprog
def getmenuitem(list,menu,line):
#validations if menu is within range
#validations if line is within range
#if all valid, find record
for obj in list:
if obj.menu == menu and obj.line == line:
return list.linename, list.linetype, list.lineprog
else:
return 'xxx','x','xxx','xxx'
#setting up the menu
menu = []
menu.append(MenuItem(0,0,'M','Tools','1'))
menu.append(MenuItem(0,1,'M','Missions','2'))
menu.append(MenuItem(0,3,'P','DoIt','all_missions(eve)'))
menu.append(MenuItem(1,0,'P','AAASetup','aaasetup()'))
menu.append(MenuItem(1,1,'P','Calibratcs','calibratecs'))
menu.append(MenuItem(2,0,'P','mission01','mission01(eve)'))
cur_menu = 0
cur_line = 0
cur_tuple = getmenuitem(menu,cur_menu,cur_line)
cur_linename = cur_tuple[0]
cur_linetype = cur_tuple[1]
cur_linedisp = cur_tuple[2]
cur_lineprog = cur_tuple[3] |
ok, I fleshed out the rest of the code, but I have no way of actually executing it. Im not in possession of our EV3. Again, I don't know how to post code that looks nice here, but I'll try. #!/usr/bin/env python3
from ev3dev2.button import Button
from globals import debug_print
import time
import ev3dev2.fonts as fonts
from ev3dev2.console import Console
class MenuItem:
def __init__(self, menu, line,linename, linetype, lineprog):
self.menu = menu
self.line = line
self.linename = linename
self.linetype = linetype
self.lineprog = lineprog
class Menu(object):
def __init(self, menu = 0, line = 0, **kwargs):
self.menu = Menu
self.line = line
#sets buttons so when called and pressed will do what was coded to do once pressed
def left(self,state):
if state:
#debug_print('Left button pressed')
self.menu = self.menu -1
if self.menu <0:
self.menu = 0
#else:
# debug_print('Left button released')
self.refreshflag = True
return 0
def right(self,state):
if state:
debug_print('right button pressed')
#self.turret.on(speed=-45)
#else:
#debug_print('right button released')
#self.turret.off()
self.refreshflag = True
return 0
def up(self,state):
if state:
debug_print('Up button pressed')
self.line = self.line -1
if self.line <0:
self.line = self.max_line
#else:
#debug_print('Up button released')
self.refreshflag = True
return 0
def down(self,state):
if state:
debug_print('Down button pressed')
self.line = self.line + 1
if self.line > self.max_line:
self.line = 0
#else:
# debug_print('Down button released')
self.refreshflag = True
return 0
def enter(self,state):
if state:
debug_print('Enter button pressed')
if self.cur_linetype == 'M':
self.cur_menu = int(self.cur_lineprog)
self.cur_line = 0
else:
self.cur_lineprog #this should run the function
#else:
# debug_print('Enter button released')
self.refreshflag = True
def getmenuitem(self,menulist,menu,line):
for obj in menulist:
if obj.menu == menu and obj.line == line:
return menulist.linename, menulist.linetype, menulist.lineprog
else:
return 'xxx','x','xxx','xxx'
def displaymenu(self,menulist,menuname, menu,line):
lcdfontB = "Lat15-TerminusBold16"
lcd = Console(font=lcdfontB)
#clear screen
lcd.reset_console()
#display menu name top center
lcd.text_at(menuname, column=1,row=1, alignment="C",inverse=True)
for obj in menulist:
if obj.menu == menu:
cur_tuple = self.getmenuitem(menu,obj.menu,obj.line)
cur_linename = cur_tuple[0]
lcd.text_at(cur_linename, column = 1,row=2+obj.line, alignment="C",inverse=(obj.line == line))
def getmaxline(self,menulist,menu):
maxline = 0
for obj in menulist:
if obj.menu == menu:
if obj.line > maxline:
maxline = obj.line
return maxline
def runmenu(self):
#set up menu names
menuname = []
menuname.append('Main')
menuname.append('Tools')
menuname.append('Missions')
#setting up the menu lines
menu = []
menu.append(MenuItem(0,0,'M',menuname[1],'1'))
menu.append(MenuItem(0,1,'M',menuname[2],'2'))
menu.append(MenuItem(0,3,'P','DoIt','all_missions(eve)'))
menu.append(MenuItem(1,0,'P','AAASetup','eve.aaasetup()'))
menu.append(MenuItem(1,1,'P','Calibratcs','eve.calibratecs()'))
menu.append(MenuItem(2,0,'P','mission01','mission01(eve)'))
menu.append(MenuItem(2,1,'P','mission02','mission02(eve)'))
menu.append(MenuItem(2,2,'P','mission03','mission03(eve)'))
cur_menu = 0
cur_line = 0
refreshflag = True
# set up button controls
btn = Button()
btn.on_left = self.left
btn.on_right = self.right
btn.on_up = self.up
btn.on_down = self.down
btn.on_enter = self.enter
while True:
if btn.check_buttons(buttons=['backspace']):
break
#calculate max_line based on menu
self.max_line = self.getmaxline(menu,cur_menu)
#display menu on screen
if refreshflag:
self.displaymenu(menu,menuname[cur_menu],cur_menu,cur_line)
refreshflag = False
btn.process()
cur_tuple = self.getmenuitem(menu,cur_menu,cur_line)
#self.cur_linename = cur_tuple[0]
self.cur_linetype = cur_tuple[1]
self.cur_lineprog = cur_tuple[2]
time.sleep(0.01) |
I edited your post to format the code; see here for documentation on how to do that in the future: https://docs.github.com/en/github/writing-on-github/creating-and-highlighting-code-blocks That looks very reasonable to me! I don't see any obvious problems, although there will likely be some debugging involved once you get it running. Minor note -- it looks like this is supposed to be lowercase def __init(self, menu = 0, line = 0, **kwargs):
self.menu = Menu |
Thank you so much for your help. If I ever get a hold of an EV3 to debug this, I'll post the final code. |
Im hoping to pick smarter people's brains on Python. If this isn't an appropriate forum, please delete this post (hopefully after you point me in the right direction ;) ).
Im trying to develop a menuing system so I can run programs from a menu once our main is run. It takes way too long for the main program to start, and in a competition, we'll not have this kind of time.
I need to create data records to be accessed like a table. Each record will have the menu number, line number, name and program to execute. As the up/down buttons are hit, the display will display accordingly like the file browser, and the center button will execute that line. Is this possible?
The text was updated successfully, but these errors were encountered: