Python 为什么当我没有(有意地)执行任何多线程时会出现错误“主线程不在主循环中”?

Python 为什么当我没有(有意地)执行任何多线程时会出现错误“主线程不在主循环中”?,python,multithreading,tkinter,Python,Multithreading,Tkinter,我正在尝试使用Tkinter制作一个类似于MS-DOS的GUI。除了按钮上的文字居中对齐外,尽管我尽了最大努力使其左对齐,它看起来很棒。我希望能够使用“回车”键选择菜单选项,通过上下箭头键来浏览我的菜单。Enter可以正常工作,但当我使用任意一个箭头键时,会出现以下错误: Unhandled exception in listener callback Traceback (most recent call last): File "C:\Users\******\AppData\Local

我正在尝试使用Tkinter制作一个类似于MS-DOS的GUI。除了按钮上的文字居中对齐外,尽管我尽了最大努力使其左对齐,它看起来很棒。我希望能够使用“回车”键选择菜单选项,通过上下箭头键来浏览我的菜单。Enter可以正常工作,但当我使用任意一个箭头键时,会出现以下错误:

Unhandled exception in listener callback
Traceback (most recent call last):
  File "C:\Users\******\AppData\Local\Programs\Python\Python37\lib\site-packages\pynput\_util\__init__.py", line 162, in inner
    return f(self, *args, **kwargs)
  File "C:\Users\******\AppData\Local\Programs\Python\Python37\lib\site-packages\pynput\keyboard\_win32.py", line 280, in _process
    self.on_press(key)
  File "C:\Users\******\AppData\Local\Programs\Python\Python37\lib\site-packages\pynput\_util\__init__.py", line 78, in inner
    if f(*args) is False:
  File "paltoydMockGUI.py", line 27, in on_press
    globals()[names[currentBtn + 1]]['state'] = 'active'
  File "C:\Users\******\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 1492, in __setitem__
    self.configure({key: value})
  File "C:\Users\******\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 1485, in configure
    return self._configure('configure', cnf, kw)
  File "C:\Users\******\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 1476, in _configure
    self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
RuntimeError: main thread is not in main loop
Traceback (most recent call last):
  File "paltoydMockGUI.py", line 59, in <module>
    listener.join()
  File "C:\Users\******\AppData\Local\Programs\Python\Python37\lib\site-packages\pynput\_util\__init__.py", line 210, in join
    six.reraise(exc_type, exc_value, exc_traceback)
  File "C:\Users\******\AppData\Local\Programs\Python\Python37\lib\site-packages\six.py", line 702, in reraise
    raise value.with_traceback(tb)
  File "C:\Users\******\AppData\Local\Programs\Python\Python37\lib\site-packages\pynput\_util\__init__.py", line 162, in inner
    return f(self, *args, **kwargs)
  File "C:\Users\******\AppData\Local\Programs\Python\Python37\lib\site-packages\pynput\keyboard\_win32.py", line 280, in _process
    self.on_press(key)
  File "C:\Users\******\AppData\Local\Programs\Python\Python37\lib\site-packages\pynput\_util\__init__.py", line 78, in inner
    if f(*args) is False:
  File "paltoydMockGUI.py", line 27, in on_press
    globals()[names[currentBtn + 1]]['state'] = 'active'
  File "C:\Users\******\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 1492, in __setitem__
    self.configure({key: value})
  File "C:\Users\******\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 1485, in configure
    return self._configure('configure', cnf, kw)
  File "C:\Users\******\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 1476, in _configure
    self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
RuntimeError: main thread is not in main loop
到目前为止,它所做的只是创建一个带有白色边框的矩形的全屏应用程序,其中包含根据名称列表标记的5个按钮,以及pynput键盘侦听器。我现在所需要的只是带箭头键的导航,但我遇到了那个讨厌的错误


任何帮助都将不胜感激

这在我的电脑里起作用了

import tkinter as tk
from pynput import keyboard

names = ['documents', 'research', 'I forgot the other buttons', 'button 4', 'button 5']
currentBtn = 0

def mkBtn(names):
    for i in range (len(names)):
        globals()[names[i]] = tk.Button (frame, justify = 'left', font = 'Unifont', bd = 0, bg = 'black', activebackground = 'white', text = str(names[i]), relief = 'flat', activeforeground = 'black', foreground = 'white', width = 200)
        globals()[names[i]].grid(row = i, column = 0, sticky = 'W')

def on_press(key):
    if key == keyboard.Key.esc:
        return False  # stop listener
    try:
        k = key.char  # single-char keys
    except:
        k = key.name  # other keys
    if k in ['up', 'down', 'enter']:  # keys of interest
        global currentBtn
        if k == 'up' and currentBtn != 0:
            globals()[names[currentBtn - 1]]['state'] = 'active'
            globals()[names[currentBtn]]['state'] = 'normal'
            currentBtn -= 1

        elif k == 'down' and currentBtn != len(names) - 1:
            globals()[names[currentBtn + 1]]['state'] = 'active'
            globals()[names[currentBtn]]['state'] = 'normal'
            currentBtn += 1

        else:
            print('works')
            print(k)

root = tk.Tk()

root.attributes("-fullscreen", True)
root.title("Test")
root.geometry('1920x1080')
root.configure(bg='black')

canvas = tk.Canvas(root, width = 1920, height = 1080, bd = '-2' , bg = 'black')
canvas.pack()

canvas.create_rectangle(71, 40, 1849, 1040, outline = 'white', fill = 'black', width = 4)

#main menu frame
frame = tk.Frame(root, bg='black');
frame.place(relx = .045, rely = .05, relwidth = .909, relheight = .9)

#labeling main menu
mkBtn(names)
documents['state'] = 'active'
listener = keyboard.Listener(on_press=on_press)

listener.start()

root.mainloop()
为什么在代码中使用块线程和while循环?Read和所有Tcl命令都需要来自同一线程。
import tkinter as tk
from pynput import keyboard

names = ['documents', 'research', 'I forgot the other buttons', 'button 4', 'button 5']
currentBtn = 0

def mkBtn(names):
    for i in range (len(names)):
        globals()[names[i]] = tk.Button (frame, justify = 'left', font = 'Unifont', bd = 0, bg = 'black', activebackground = 'white', text = str(names[i]), relief = 'flat', activeforeground = 'black', foreground = 'white', width = 200)
        globals()[names[i]].grid(row = i, column = 0, sticky = 'W')

def on_press(key):
    if key == keyboard.Key.esc:
        return False  # stop listener
    try:
        k = key.char  # single-char keys
    except:
        k = key.name  # other keys
    if k in ['up', 'down', 'enter']:  # keys of interest
        global currentBtn
        if k == 'up' and currentBtn != 0:
            globals()[names[currentBtn - 1]]['state'] = 'active'
            globals()[names[currentBtn]]['state'] = 'normal'
            currentBtn -= 1

        elif k == 'down' and currentBtn != len(names) - 1:
            globals()[names[currentBtn + 1]]['state'] = 'active'
            globals()[names[currentBtn]]['state'] = 'normal'
            currentBtn += 1

        else:
            print('works')
            print(k)

root = tk.Tk()

root.attributes("-fullscreen", True)
root.title("Test")
root.geometry('1920x1080')
root.configure(bg='black')

canvas = tk.Canvas(root, width = 1920, height = 1080, bd = '-2' , bg = 'black')
canvas.pack()

canvas.create_rectangle(71, 40, 1849, 1040, outline = 'white', fill = 'black', width = 4)

#main menu frame
frame = tk.Frame(root, bg='black');
frame.place(relx = .045, rely = .05, relwidth = .909, relheight = .9)

#labeling main menu
mkBtn(names)
documents['state'] = 'active'
listener = keyboard.Listener(on_press=on_press)

listener.start()

root.mainloop()