我正在编写一个Python程序来监听RFID输入,只有在出现有效令牌时才会运行。该程序还有一个我想用TkInter构建的GUI。
这个拼图的两个部分都是孤立的,但是现在我似乎能够选择其中一个 - 但不是两个都可以!我可以很好地绘制我的TkInter窗口,但是如果我调用该函数开始侦听RFID输入然后该位运行正常并且工作......那里没有GUI。
代码如下。到目前为止,您可以看到我的打印输出到终端的调试工作......
#!/usr/bin/env python3 import sys import MySQLdb if sys.version_info[0] == 2: from Tkinter import * import Tkinter as ttk else: from tkinter import * import tkinter as ttk class Fullscreen_Window: def __init__(self): self.tk = Tk() self.frame = Frame(self.tk) self.frame.pack() ttk.Button(self.tk, text="hello world").pack() self.tk.attributes('-zoomed', True) self.state = False self.tk.bind("<F11>", self.toggle_fullscreen) self.tk.bind("<Escape>", self.end_fullscreen) print("init running") self.listen_rfid() # Commenting this out makes the GUI appear, uncommenting means no GUI :( def toggle_fullscreen(self, event=None): self.state = not self.state # Just toggling the boolean self.tk.attributes("-fullscreen", self.state) print("Toggling") return "break" def end_fullscreen(self, event=None): self.state = False self.tk.attributes("-fullscreen", False) return "break" def listen_rfid(self): print("Main loop running") 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") else: user_info = cur.fetchone() print("Welcome %s!!" % (user_info['name'])) tty.close() listen_rfid() if __name__ == '__main__': w = Fullscreen_Window() w.tk.mainloop()
我确定它的确非常简单但是因为我是Python / TkInter n00b它击败了我并且我完成了谷歌搜索。感谢任何帮助:)
答案 0 :(得分:3)
Tkinter(以及所有GUI)都有一个名为mainloop的无限循环,可以保持GUI的活动和响应。当你进行另一个无限循环(// first approach
angular.controller("MyController", function() {
$scope.firstFun = function() {
// do something here
};
});
// second approach
var firstFun = function($scope) {
return function() {
//use scope here and declare logic also
};
};
angular.controller("MyController", function() {
$scope.firstFun = firstFun($scope);
});
)时,你阻止了Tkinter的主循环;并且GUI失败。你需要将循环放在一个单独的线程中,或者使用Tkinter的主循环来完成你的工作。由于您使用了阻塞while True
,因此该线程是最好的方法。猜测一下,用这个替换你的电话:
readline
编辑:BTW,你的进口非常糟糕。 &#34; TTK&#34;是tkinter的子集,而不是别名,别名&#34; tk&#34;通常用于tkinter,通配符导入很糟糕,应该避免。这就是你的tkinter导入的样子:
from threading import Thread
t = Thread(target=self.listen_rfid)
t.daemon = True # this line tells the thread to quit if the GUI (master thread) quits.
t.start()
然后使用适当的前缀:
try:
# python 2
import Tkinter as tk
import ttk
except ImportError:
# python 3
import tkinter as tk
from tkinter import ttk
答案 1 :(得分:2)
您应该使用listen_rfid
运行after
。问题是listen_rfid就像你写的那样会永远运行,这意味着mainloop
永远不会启动。如果你这样做:
#!/usr/bin/env python3
import sys
import select
import MySQLdb
if sys.version_info[0] == 2:
from Tkinter import *
import Tkinter as ttk
else:
from tkinter import *
import tkinter as ttk
class Fullscreen_Window:
def __init__(self):
self.tk = Tk()
self.frame = Frame(self.tk)
self.frame.pack()
ttk.Button(self.tk, text="hello world").pack()
self.tk.attributes('-zoomed', True)
self.state = False
self.tk.bind("<F11>", self.toggle_fullscreen)
self.tk.bind("<Escape>", self.end_fullscreen)
print("init running")
# Schedule self.listen_rfid to run after the mainloop starts
self.tk.after(0, self.listen_rfid)
def toggle_fullscreen(self, event=None):
self.state = not self.state # Just toggling the boolean
self.tk.attributes("-fullscreen", self.state)
print("Toggling")
return "break"
def end_fullscreen(self, event=None):
self.state = False
self.tk.attributes("-fullscreen", False)
return "break"
def listen_rfid(self):
print("Main loop running")
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)
# readline is blocking so check that there is input
# before attempting to read it.
r, w, x = select.select([sys.stdin], [], [], 0)
if r:
# There is available input, so read a line.
RFID_input = sys.stdin.readline().rstrip()
cur.execute("SELECT * FROM access_list WHERE rfid_code = '%s'" % (RFID_input))
if cur.rowcount != 1:
print("ACCESS DENIED")
else:
user_info = cur.fetchone()
print("Welcome %s!!" % (user_info['name']))
# keep running every 500 milliseconds for as long as
# the mainloop is active.
self.tk.after(500, self.listen_rfid)
if __name__ == '__main__':
w = Fullscreen_Window()
w.tk.mainloop()
它将每半秒检查命令行上是否有一些输入并处理它。