Python Forum
How to create an app manager
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to create an app manager
#1
Hello! Please help me!
I'm trying to create an application manager with Tkinter and I want the desktop['application#'] variables to open applications with names being SAME as the text on the buttons!
Here is my lambda:
func['run'] = lambda: "try: \n\texec(open('Applications/' + str(application{0}['text']) + '.py').read()) \nexcept Exception as err: \n\tprint(err)"
aka
try: 
	exec(open('Applications/' + str(application{0}['text']) + '.py').read()) 
except Exception as err: 
	print(err)
And the Desktop creator
def manager():
    desktop = {}
    desktop['workspace'] = Canvas(corwin, bd=100)
    desktop['workspace'].place(x=105, y=0, relwidth=0.9, relheight=1, anchor=NW)
    desktop['openStorage'] = open('Applications/apps.corwin')
    desktop['readStorage'] = ast.literal_eval(desktop['openStorage'].read())
    for x in range(len(list(desktop['readStorage'].values()))):
        temp['desktopDict'] = str(list(desktop['readStorage'].keys())[x])
        desktop['application{0}'.format(x)] = Button(corwin, text=(str(desktop['readStorage'][str(temp['desktopDict'])]) + ' '), anchor='e', bg='black', font=('DIN Alternate', '15'), command=lambda: [exec("try: \n\texec(open('Applications/' + application0.cget('text') + '.py').read()) \nexcept Exception as err: \n\tprint(err)")])
        desktop['application{0}'.format(x)].place(x=100, y=(25*x), width=100, anchor=NE)
The Tkinter:
[Image: 9T4BE.png?trs=11b5a3f71afa486346eb25a5b3...9cc55fa4e3]
The output:
Output:
name 'application0' is not defined name 'application0' is not defined name 'application0' is not defined name 'application0' is not defined name 'application0' is not defined name 'application0' is not defined name 'application0' is not defined name 'application0' is not defined name 'application0' is not defined
(I clicked those buttons this much)

Please help as soon as possible!! Thank you!
Reply
#2
What's with all the dictionaries? Makes your code really hard to read.

What does the Applications/apps.corwin file look like?
Reply
#3
(Aug-13-2020, 01:35 PM)deanhystad Wrote: What's with all the dictionaries? Makes your code really hard to read.

What does the Applications/apps.corwin file look like?
Not sure if that matters bc its a catalog with shortcut file names to the file paths, but here:
Output:
{'apps.corwin': 'apps', 'manager.py': 'manager'}
Reply
#4
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()
Output:
Popeye name 'locname' is not defined
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
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 be name:command where command is whatever text you would evaluate to run the command.
{'manager':'python manager.py'}
Reply
#5
(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()
Output:
Popeye name 'locname' is not defined
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
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 be name: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.

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()
Output:
Popeye name 'locname' is not defined
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
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 be name:command where command is whatever text you would evaluate to run the command.
{'manager':'python manager.py'}
Wow! That was so useful! But would those functions work if I convert them into a one string function?
Reply
#6
What do you mean by "one string function"?
Reply
#7
(Aug-14-2020, 01:03 PM)deanhystad Wrote: What do you mean by "one string function"?

Use \n s instead of new-line signs
Reply
#8
Quote:Wow! That was so useful! But would those functions work if I convert them into a one string function?
What do you mean by this? Too what functions are you referring?
Reply
#9
(Aug-17-2020, 12:28 PM)deanhystad Wrote:
Quote:Wow! That was so useful! But would those functions work if I convert them into a one string function?
What do you mean by this? Too what functions are you referring?

Hello.
I'm glad that you contributed to this thread as I'm closing it because I found the answer on stackoverflow.
Thank you.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Context Manager (with) wyattbiker 3 3,774 Jul-23-2018, 03:19 PM
Last Post: snippsat

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020