0

I borrowed some code from another thread I found on this website, but when I tried to form a program around it, I found that one of my functions can only be called once.

import tkinter as tk

def total():
    #borrowed code vvv
    def keyDetect(event):
        root.destroy()
        if event.char == event.keysym:
            print(event.char)
        elif len(event.char) == 1:
            print(event.keysym, event.char)
        else:
            print(event.keysym)


    root = tk.Tk()
    root.bind_all('<Key>', keyDetect)
    root.withdraw()
    root.mainloop()
    #borrowed code ^^^

total()
print('test message #1')
total()

When this code is run, the definition 'total()' works the first time, but not the second. Why? And how do I fix it?

Thanks in advance!


EDIT:

If you remove the definition completely, the code still doesn't work

import tkinter as tk

def keyDetect(event):
    root.destroy()
    if event.char == event.keysym:
        print(event.char)
    elif len(event.char) == 1:
        print(event.keysym, event.char)
    else:
        print(event.keysym)


root = tk.Tk()
root.bind_all('<Key>', keyDetect)
root.withdraw()
root.mainloop()

print('1')
root = tk.Tk()
root.bind_all('<Key>', keyDetect)
print('2')
root.withdraw()
print('3')
root.mainloop()
print('4')

But doing this does show where the problem is; as when this code is run "3" is printed, but "4" isn't.

Community
  • 1
  • 1
Toby Smith
  • 1,505
  • 2
  • 15
  • 24
  • 1
    Sounds like there's a generator/iterator somewhere maybe – Cory Kramer Jan 16 '15 at 20:15
  • @Cyber Is it something you could fix, this is my first experience with tkinter. – Toby Smith Jan 16 '15 at 20:19
  • Why you didn't just copy-paste that `def key()` function instead of making another function and taking it as a parameter? –  Jan 16 '15 at 20:22
  • Tkinter is a bit impractical for this purpose. Consider using `win32api.GetKeyState` to determine whether a key is pressed or not. (you may need to [install](http://www.lfd.uci.edu/~gohlke/pythonlibs/) pywin32 first) – Kevin Jan 16 '15 at 20:28
  • @user3075190 You must be more specific, you didn't mention that `print('test message')` is printed. –  Jan 16 '15 at 20:31
  • Sorry! But yeah, the 'test print' does work. – Toby Smith Jan 16 '15 at 20:33

1 Answers1

1

TkInter is not the right library for console interaction. Use curses instead. Otherwise, your program won't work without the DISPLAY variable defined (i.e. when not run in X11). I tried your program on Ubuntu 14.10 and it doesn't capture any events at all. If I comment out root.withdraw(), both calls to total() work.

proski
  • 3,603
  • 27
  • 27
  • Ok, @proski . Can you show me an example of what you mean? – Toby Smith Jan 16 '15 at 20:42
  • Question is `why I can call my definition only once`. Your answer is not even relevant actually. –  Jan 16 '15 at 20:42
  • @user3075190 I've posted an example how to use curses at http://stackoverflow.com/questions/4204714/how-to-get-input-as-a-left-arrow-key/27993526#27993526 – proski Jan 16 '15 at 22:05
  • @Defalt So is it because an infinite loop is being created the first time, that therefore cannot be re-started the second time? – Toby Smith Jan 16 '15 at 22:15
  • @proski yeah, that didn't work. `AttributeError: 'module' object has no attribute 'initscr'` – Toby Smith Jan 16 '15 at 22:21
  • @user3075190 I guess you gave some unfortunate name to the file, like curses.py. Try a name that doesn't conflict with standard modules. – proski Jan 16 '15 at 23:28
  • @proski yes, that is correct. But now I get this: `File "C:\Python34\lib\curses\__init__.py", line 13, in from _curses import * ImportError: No module named '_curses'` – Toby Smith Jan 16 '15 at 23:38
  • @user3075190 This question was asked and answered on StackOverflow, just like the question about "module object has no attribute". – proski Jan 17 '15 at 00:01