0

I was trying to create a simple app for illustration purposes. The idea is as follows: Create an application which will run script files associated only to the selected courses (radio buttons). So, I create radio buttons which list out subjects (to click on). Once the subjects are selected the user has to hit the Enter button. This should run all the .py files for the selected subjects (execute_script function).

However, when I run my code, I get 4 messageboxes with 'None' written inside. After clicking ok on them, I get a square windows with only the enter button. What can I do to correct this problem?

def check(file_name, relStatus):   
    radioValue = relStatus.get()
    tkMessageBox.showinfo('You checked', radioValue)
    been_clicked.append(file_name)   
    return

def execute_script():
    for name in been_cliked:
        subprocess.Popen(['python', 'C:\Users\Max\Subjects\{}'.format(name)])

    yield


def main():

    #Create application
    app = Tk()
    app.title('Coursework')
    app.geometry('450x300+200+200')

    #Header
    labelText = StringVar()
    labelText.set('Select subjects')

    #Dictionary with names
    product_names = {}
    names = []
    file_name = []
    names = ['Math', 'Science', 'English', 'French']
    file_name = ['calc.py', 'physics.py', 'grammar.py', 'livre.py']
    product_names = OrderedDict(zip(names, file_name))

    #Create radio buttons
    global been_clicked
    been_clicked = []
    relStatus = StringVar()
    relStatus.set(None)
    for name,file_name in product_names.iteritems():
        radio1 = Radiobutton(app, text=name, value=name, \
                         variable=relStatus, command=check(file_name, relStatus))

    button = Button(app, text='Click Here', width=20, command=execute_script())
    button.pack(side='bottom', padx=15, pady=15)

    app.mainloop()


if __name__ == '__main__': main()

1 Answer 1

4

There are a few issues with your script:

1) A typo in your execute_script() function: for name in been_cliked

2) You are actually calling the check() function when you create your radio buttons. That's why you're seeing the windows pop up when you run your program.

You need to change this:

radio1 = Radiobutton(app, text=name, value=name, \
                     variable=relStatus, command=check(file_name, relStatus))

to this:

radio1 = Radiobutton(app, text=name, value=name, \
                     variable=relStatus, command=check)

See how check no longer has brackets? That's means you're passing the function name as an argument, instead of actually calling the function. Of course, you'll see an immediate problem is that you can no longer pass arguments to your callback function! That's a bigger issue. Here's a couple links to help get you started:

Here is the solution:

Change this:

command=check(file_name, reStatus)

to this:

command = lambda: check(file_name, relStatus)

3) You don't actually pack() your radio buttons anywhere. Add something like this just after you create your radio buttons in your for loop: radio1.pack(side='top')

4) You have the same problem with your callback for your Click Here button. You need to change your command to not call the function, but just refer to it: command = execute_script

5) In execute_script(), make sure you import subprocessing

6) Are you sure you want yield instead of return in your execute_script() function?

7) In all your functions, you need to make sure that been_clicked is global.

I think if you fix these issues you'll be closer to getting what you're looking for. Good luck.!

Sign up to request clarification or add additional context in comments.

4 Comments

Strange that the for name in been_cliked problem doesn't result in a NameError: global name 'been_cliked' is not defined error since the , command=execute_script() is calling execute_script.
I agree. The reason is he has yield instead of return. Using yield won't cause NameError to be raised. Not sure why that is though.
Ah, the answer lies here: stackoverflow.com/questions/231767/… yield causes a generator to be returned, but until that generated is used, the code hasn't been run yet.
Indeed...mystery explained. To save folks the trouble of looking it up, here's the key paragraph about generator functions from @e-satis, et al's excellent answer: "To master yield, you must understand that when you call the function, the code you have written in the function body does not run. The function only returns the generator object, this is a bit tricky :-)"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.