如果调用另一个函数,则不会加载TkInter框架
我正在编写一个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,它已经被我殴打,我都完成了谷歌搜索。 任何帮助感激地收到:)
Tkinter(以及所有的GUI)都有一个叫做mainloop的无限循环,使GUI保持活跃和响应。 当你进行另一次无限循环( while True
)时,你会阻止Tkinter的主循环; 并且GUI失败。 您需要将您的循环放在单独的线程中,或者使用Tkinter的主循环来完成您的工作。 由于您正在使用阻塞readline
,因此该线程是最佳途径。 作为一个猜测,用这个替换你的电话:
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()
编辑:顺便说一句,你的进口是非常糟糕的。 “ttk”是tkinter的一个子集,不是别名,别名“tk”通常用于tkinter,通配符导入不好,应该避免。 这就是你的tkinter导入应该看起来的样子:
try:
# python 2
import Tkinter as tk
import ttk
except ImportError:
# python 3
import tkinter as tk
from tkinter import ttk
然后你使用适当的前缀:
self.tk = tk.Tk()
self.frame = tk.Frame(self.tk)
你应该使用after
来运行listen_rfid
。 问题是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()
它会每半秒检查命令行是否有输入并处理它。
链接地址: http://www.djcxy.com/p/65023.html上一篇: TkInter Frame doesn't load if another function is called