Почему я получаю сообщение об ошибке «основной поток не в основном l oop», когда я (целенаправленно) не выполняю многопоточность? - PullRequest
0 голосов
/ 22 марта 2020

Я пытаюсь сделать GUI, используя Tkinter, похожий на MS-DOS. Несмотря на то, что текст на кнопках выровнен по центру, несмотря на все мои попытки выровнять их по левому краю, он выглядит великолепно. Я хотел иметь возможность перемещаться по моему меню с помощью клавиш со стрелками вверх и вниз, используя «enter», чтобы выбрать пункт меню. 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

Кажется, что ошибка связана с многопоточностью, но я думал, что не возиться с любым из этого. Вот мой код:

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)

while 1:
    root.update()
    listener.start()
    listener.join()

Пока все, что он делает, это создает полноэкранное приложение с прямоугольником с белой рамкой, содержащим 5 кнопок, помеченных в соответствии со списком имен, а также прослушиватель клавиатуры pynput. Все, что мне сейчас нужно, это навигация с помощью клавиш со стрелками, но я получаю эту досадную ошибку.

Любая помощь будет принята с благодарностью!

1 Ответ

0 голосов
/ 22 марта 2020

Это сработало на моем компьютере.

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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...