Aug-14-2020, 07:05 AM
(Aug-13-2020, 09:55 PM)deanhystad Wrote: There are a few things going on here.
The first problem is the arg for the inner exec is not a string.
exec(open('Applications/' + application0.cget('text') + '.py').read())Because the arg is not a string it tries to find application0, and that does not exist anywhere.
There is a desktop['application0'], but that does you little good. By the time you press the button and execute the lambda, desktop is long gone. In the example below the f2 lambda references a variable local to f2. This raises a NameError exception. f1 references a module variable and it works.
globname = 'Popeye' def f1(): command = lambda: [exec("try: \n\texec('print(globname)') \nexcept Exception as err: \n\tprint(err)")] command() def f2(): locname = globname command = lambda: [exec("try: \n\texec('print(locname)') \nexcept Exception as err: \n\tprint(err)")] command() f1() f2()But there is a far better solution. Use a partial. Partial function arguments are evaluated when the partial is created, not when the partial is executed. This lets you use local variables in a partial. Below I have a callback function to run the app when a button is pressed. The 'app' argument is the text you would evaluate to run the application
Output:Popeye name 'locname' is not defined
from functools import partial def runapp(app): try: popen(app) except Exception as err: print(err) def manager(): desktop = {} canvas = Canvas(corwin, bd=100) canvas.place(x=105, y=0, relwidth=0.9, relheight=1, anchor=NW) appfile = open('Applications/apps.corwin') apps = ast.literal_eval(appfile.read()) for appname, appcmd in apps.items() btn = Button(corwin, text=(appname), anchor='e', bg='black', font=('DIN Alternate', '15'), \ command=partial(runapp, appcmd) btn.place(x=100, y=(25*x), width=100, anchor=NE)I would change the app file to to bename:command
where command is whatever text you would evaluate to run the command.
{'manager':'python manager.py'}
(Aug-13-2020, 09:55 PM)deanhystad Wrote: There are a few things going on here.Wow! That was so useful! But would those functions work if I convert them into a one string function?
The first problem is the arg for the inner exec is not a string.
exec(open('Applications/' + application0.cget('text') + '.py').read())Because the arg is not a string it tries to find application0, and that does not exist anywhere.
There is a desktop['application0'], but that does you little good. By the time you press the button and execute the lambda, desktop is long gone. In the example below the f2 lambda references a variable local to f2. This raises a NameError exception. f1 references a module variable and it works.
globname = 'Popeye' def f1(): command = lambda: [exec("try: \n\texec('print(globname)') \nexcept Exception as err: \n\tprint(err)")] command() def f2(): locname = globname command = lambda: [exec("try: \n\texec('print(locname)') \nexcept Exception as err: \n\tprint(err)")] command() f1() f2()But there is a far better solution. Use a partial. Partial function arguments are evaluated when the partial is created, not when the partial is executed. This lets you use local variables in a partial. Below I have a callback function to run the app when a button is pressed. The 'app' argument is the text you would evaluate to run the application
Output:Popeye name 'locname' is not defined
from functools import partial def runapp(app): try: popen(app) except Exception as err: print(err) def manager(): desktop = {} canvas = Canvas(corwin, bd=100) canvas.place(x=105, y=0, relwidth=0.9, relheight=1, anchor=NW) appfile = open('Applications/apps.corwin') apps = ast.literal_eval(appfile.read()) for appname, appcmd in apps.items() btn = Button(corwin, text=(appname), anchor='e', bg='black', font=('DIN Alternate', '15'), \ command=partial(runapp, appcmd) btn.place(x=100, y=(25*x), width=100, anchor=NE)I would change the app file to to bename:command
where command is whatever text you would evaluate to run the command.
{'manager':'python manager.py'}