当前位置: 首页 > 知识库问答 >
问题:

如何获取TkInter GUI(不是shell提示符)来侦听来自/dev/stdin的输入

张宝
2023-03-14

我正在编写一个带有图形用户界面的Python程序,该图形用户界面监听正在呈现的射频识别令牌(使用模拟键盘输入的USB阅读器)。我有问题,键盘/射频识别输入只有在我启动脚本的终端有焦点时才会被监听和操作。

如果GUI被聚焦,所有的输入都会被忽略,但是当终端被聚焦时,它会正常工作,甚至会向GUI和shell发送更新。我尝试在GUI上绘制文本输入框,但没有成功。

我想知道这是否与它需要如何使用多线程、队列甚至进程有关——有人能帮我更好地理解它吗?

代码如下,提前感谢!

#!/usr/bin/env python3
import sys
import MySQLdb

try:
    # python 2
    import Tkinter as tk
    import ttk
except ImportError:
    # python 3
    import tkinter as tk
    from tkinter import ttk

from threading import Thread

class Fullscreen_Window:

def __init__(self):
    self.tk = tk.Tk()
    self.tk.title("Listening for RFID token...")
    self.frame = tk.Frame(self.tk)
    self.frame.pack()

    self.tk.attributes('-zoomed', True)
    self.state = False
    self.tk.bind("<F11>", self.toggle_fullscreen)
    self.tk.bind("<Escape>", self.end_fullscreen)
    self.tk.config(cursor="none")

    t = Thread(target=self.listen_rfid)
    t.daemon = True
    t.start()

def toggle_fullscreen(self, event=None):
    self.state = not self.state  # Just toggling the boolean
    self.tk.attributes("-fullscreen", self.state)
    return "break"

def end_fullscreen(self, event=None):
    self.state = False
    self.tk.attributes("-fullscreen", False)
    return "break"

def listen_rfid(self):
    dbHost = 'localhost'
    dbName = 'python'
    dbUser = 'python'
    dbPass = 'PASSWORD'

    dbConnection = MySQLdb.connect(host=dbHost, user=dbUser, passwd=dbPass, db=dbName)
    cur = dbConnection.cursor(MySQLdb.cursors.DictCursor)

    with open('/dev/stdin', 'r') as tty:
        while True:
            RFID_input = tty.readline().rstrip()
            cur.execute("SELECT * FROM access_list WHERE rfid_code = '%s'" % (RFID_input))

            if cur.rowcount != 1:
                print("ACCESS DENIED")
                ttk.Label(self.tk, text="ACCESS DENIED").pack()
            else:
                user_info = cur.fetchone()
                print("Welcome %s!!" % (user_info['name']))
                ttk.Label(self.tk, text="Welcome %s!!" % (user_info['name'])).pack()
    tty.close()


if __name__ == '__main__':
w = Fullscreen_Window()
w.tk.mainloop()

共有1个答案

苏昊英
2023-03-14

经过多次的挠头,我再次找到了这条线索,并重新正确地阅读了它,然后意识到它包含了我想要的答案,尽管需要我做一点工作。

我的listen\u rfid功能现在看起来像下面的代码。希望对遇到我问题的人有用!

关键是查看/dev/input/by id并找到您的设备,将有一个符号链接(至少在我的Raspbian安装中有)指向更优雅的东西,例如,在我的例子中,“/event0”-如下)。然后,您可以使用pythonevdev来读取它。

如果您没有python evdev,只需使用sudo pip install evdev

以下是工作代码:

def listen_rfid(self):
    dbHost = 'localhost'
    dbName = 'python'
    dbUser = 'python'
    dbPass = 'PASSWORD'

    dbConnection = MySQLdb.connect(host=dbHost, user=dbUser, passwd=dbPass, db=dbName) # ToDo: This needs some error handling for if MySQL has gone away, and reconnect.
    cur = dbConnection.cursor(MySQLdb.cursors.DictCursor)

    from evdev import InputDevice
    from select import select

    keys = "X^1234567890XXXXqwertzuiopXXXXasdfghjklXXXXXyxcvbnmXXXXXXXXXXXXXXXXXXXXXXX"
    dev = InputDevice('/dev/input/event0')
    rfid_presented = ""

    while True:
       r,w,x = select([dev], [], [])
       for event in dev.read():
            if event.type==1 and event.value==1:
                    if event.code==28:
                        #print("RFID: " + str(rfid_presented))

                        cur.execute("SELECT * FROM access_list WHERE rfid_code = '%s'" % (rfid_presented))

                        if cur.rowcount != 1:
                            #print("ACCESS DENIED")
                            ttk.Label(self.tk, text="ACCESS DENIED").pack()
                        else:
                            user_info = cur.fetchone()
                            #print("Welcome %s!!" % (user_info['name']))
                            ttk.Label(self.tk, text="Welcome %s!!" % (user_info['name'])).pack()

                        rfid_presented = ""
                    else:
                        rfid_presented += keys[ event.code ]
 类似资料:
  • 问题内容: 我已经在Windows上(在本地计算机上)成功地将MongoDB安装为服务,但是现在我想将MongoDb移到单独的服务器上。因此,我将压缩包解压缩到网络上的虚拟服务器(正在运行linux)。 当我从本地计算机使用PuTTY连接到服务器(“ testmongoserver”)时,我启动了mongod服务器,它告诉我它正在侦听默认的28017端口。mongo控制台也正在运行,并允许我创建一

  • 我的目标是向用户显示一个对话框,以便用户能够选择要添加到舞台上的演员。我在实现Screen和GestureListener的应用程序的主屏幕中执行此操作。(我需要手势监听器来听双击)。我在重写的touchtown()方法中创建对话框。当对话框出现时,它不工作。如果我点击屏幕上的任何一点,屏幕会一直监听着地的输入。 代码如下:

  • 任何人都可以解释为什么以下程序在关闭子窗口时不会终止? 我已经创建了一个简单的应用程序,它具有一个父<code>JFrame</code>,它使用<code>JDialog</code>实例化一个子类。当我将父引用传递到子类中,以便可以使用父类创建时(即:),从父类添加到它的窗口监听器会导致程序在子窗口关闭后永远不会终止。窗口确实关闭(在可见性方面),但程序本身仍在运行。父级的默认关闭操作设置为。

  • 我正在处理JButton事件。我有一个JPanel类,我们叫Panel1,包含一个公共的JButton,我们叫它Button1。单击此按钮时: 但我有兴趣: 有什么建议吗?

  • 问题内容: 如何获取命令提示符的输出,这意味着我已经打开了这样的命令提示符。 我无法获得像这样的cmd输出 那么如何获得命令提示符输出? 问题答案: 这不是Java问题。基本上,您正在执行的是Java(Java Main Process A),然后从中启动另一个进程(Windows CMD B)。很好,您可以在Java(A)中获得此过程(B)的输入/输出流。但是,此过程(B)使用其自己的标准输入/

  • 好吧,所以我正在做这个项目,你必须做一些来自用户的输入 让我们说如果他进入 "12 3" 但他没有输入第二个输入 如果我把它叫做 如果我打电话 我有错误。我如何检查是否没有第二次输入? 公共静态void main(String [] args)引发IOException{ 如果用户输入 "3 2" 但没有进入第二个...我得到nullpointerx0016