Я пытаюсь сделать 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. Все, что мне сейчас нужно, это навигация с помощью клавиш со стрелками, но я получаю эту досадную ошибку.
Любая помощь будет принята с благодарностью!