在tkinter文本框中显示python print()



我想在tkinter的文本框中实时显示键盘记录程序的python print((语句。

到目前为止,我可以使用窗口或键盘记录器通过print((命令写入控制台(spyder(,但不能同时使用两者。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import tkinter
import tkinter.scrolledtext
from pynput import keyboard

def on_press(key):
try:
print('Alphanumeric key pressed: {0} '.format(key.char))
except AttributeError:
print('Special key pressed: {0}'.format(key))
def on_release(key):
print('Key released: {0}'.format(key))
# Stop the listener
if key == keyboard.Key.esc:
return False

# Main window
main = tkinter.Tk()
main.title('keyboad Logger')
main.geometry('500x400')

# Scrollable Textbox
txt = tkinter.scrolledtext.ScrolledText(main, width = 40, height = 30)
# Insert into Textbox
txt.insert(tkinter.END, "Some text here")
txt.pack()
# main.mainloop()
# Collect events until released
with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()
pynput侦听器在另一个线程中运行,因此当您加入该线程时,tkinter线程会被阻塞。因此,您的GUI不会显示。这也造成了另一个问题,因为tkinter不能与多个线程一起工作,因此需要有一种方法在侦听器线程和tkinter线程之间进行通信。您也不能在线程上使用.join(),因为这会阻塞tkinter。
def on_press(key, print_list):
try:
print_list.append('Alphanumeric key pressed: {0} '.format(key.char))
except AttributeError:
print_list.append('Special key pressed: {0}'.format(key))
def on_release(key, print_list):
print_list.append('Key released: {0}'.format(key))
print(print_list)
# Stop the listener
if key == keyboard.Key.esc:
return False
def check_print():
global print_list
if print_list != []:
for item in print_list:
txt.insert(tkinter.END, item + "n")
print_list = []
main.after(100, check_print)
# Main window
main = tkinter.Tk()
main.title('keyboad Logger')
main.geometry('500x400')

# Scrollable Textbox
print_list = []
txt = tkinter.scrolledtext.ScrolledText(main, width = 40, height = 30)
# Insert into Textbox
txt.insert(tkinter.END, "Some text here")
txt.pack()
# Collect events until released
listener = keyboard.Listener(on_press=lambda key: on_press(key, print_list), on_release=lambda key: on_release(key, print_list), supress = True)
listener.start()
check_print()
main.mainloop()

为了解决第一个问题,我改变了侦听器线程的工作方式。现在,我们不加入会阻塞GUI的线程,而是在后台使用.start()启动线程。为了在两个线程之间进行通信,我添加了一个名为print_list的列表。它作为on_presson_release的参数从主程序传递到侦听器线程。然后,当某个东西本来应该打印出来时,它现在被附加到列表中。现在正在记录密钥,但GUI还没有显示,所以我添加了check_print功能。它首先在侦听线程启动后调用,然后每100ms由它自己调用一次,以检查print_list。如果其中有内容,则会将其插入到文本小部件中,然后设置为空。该程序现在按预期运行。

最新更新