我正在努力获得一个简单的GUI,以便在Raspberry Pi(Buster)上使用python(2.7)。
我已经尝试过Tkinter和PySimpleGUI,但是它们都有效地使用了while循环和 我的程序中已经有这样的循环,可以正常工作。 Tkinter和PySimpleGUI都阻塞了主循环。
尝试在线程中运行Tkinter和PySimpleGUI似乎不起作用, 各种元素与线程不兼容,并挂有各种错误消息。 无论如何,似乎一旦进入线程,您将无法与GUI小部件进行交互 除非您创建复杂的队列并且它们不是线程安全的。
我要做的就是写出'Alert Door'打印语句(while循环的最后一行) 进入文本字段(漂亮/彩色的东西) 然后有一个警报声(GPIO)和一个用于清除警报和文本字段的按钮。
任何想法都令人惊讶,似乎可用的Pi GUI不合适。 温柔一点,我是新手。
def vp_start_gui():
#'''Starting point when module is the main routine.'''
global val, w, root
root = tk.Tk()
top = Toplevel1 (root)
redalert_support.init(root, top)
root.mainloop()
w = None
def destroy_Toplevel1():
global w
w.destroy()
w = None
class Toplevel1:
def __init__(self, top=None):
'''This class configures and populates the toplevel window.
top is the toplevel containing window.'''
_bgcolor = '#d9d9d9' # X11 color: 'gray85'
_fgcolor = '#000000' # X11 color: 'black'
_compcolor = '#d9d9d9' # X11 color: 'gray85'
_ana1color = '#d9d9d9' # X11 color: 'gray85'
_ana2color = '#ececec' # Closest X11 color: 'gray92'
font13 = "-family {Segoe UI} -size 22"
font14 = "-family {Segoe UI} -size 21"
top.geometry("480x300+267+205")
top.minsize(120, 1)
top.maxsize(1028, 749)
top.resizable(1, 1)
top.title("SecuriCode RedAlert")
top.configure(background="#4339fb")
self.Button1 = tk.Button(top)
self.Button1.place(relx=0.333, rely=0.667, height=54, width=177)
self.Button1.configure(activebackground="#ececec")
self.Button1.configure(activeforeground="#000000")
self.Button1.configure(background="#ffff00")
self.Button1.configure(cursor="fleur")
self.Button1.configure(disabledforeground="#a3a3a3")
self.Button1.configure(font=font14)
self.Button1.configure(foreground="#000000")
self.Button1.configure(highlightbackground="#d9d9d9")
self.Button1.configure(highlightcolor="black")
self.Button1.configure(pady="0")
self.Button1.configure(text='''Clear Alarm''')
self.Text1 = tk.Text(top)
self.Text1.place(relx=0.125, rely=0.133, relheight=0.423, relwidth=0.756)
self.Text1.configure(background="white")
self.Text1.configure(font=font13)
self.Text1.configure(foreground="black")
self.Text1.configure(highlightbackground="#d9d9d9")
self.Text1.configure(highlightcolor="black")
self.Text1.configure(insertbackground="black")
self.Text1.configure(selectbackground="#c4c4c4")
self.Text1.configure(selectforeground="black")
self.Text1.configure(wrap="word")
vp_start_gui()
while 1:
#Receive data from LAN device
reply = s.recv(34)
#Receive replies from SMS Gateway
#smsreply = g.recv(34)
#Check for Lan device keep alive replies
if reply.find(alivereply) != -1:
#print 'Device alive'
print reply
#Check for valid Tag strings
if reply.find(tagstring) != -1:
print 'Tag string received'
print reply
#Send SMS alert message
doorcode = reply[5:6]
doornumber = int(doorcode, 16)
#print doornumber
tagcode = reply[8:9]
tagnumber = int(tagcode, 16)
#print tagnumber
print 'Alert Door ' +str(doornumber) + ' Tag ' +str(tagnumber)
答案 0 :(得分:1)
Tkinter和PySimpleGUI都阻塞了主循环。
并非总是如此。以我的经验,阻止tkinter阻止主程序循环的最佳解决方案是使用root_window.update()
而不是root_window.mainloop()
。
使用此方法,您可以不断迭代while循环,还可以更新tkinter窗口。
希望这会有所帮助。
更新
在您进行编辑之后,我亲自查看了您的代码。
我更改了函数vp_start_gui()
并在循环外创建了根窗口。此代码的主要目的是让您了解如何正确实现tkinter窗口。将鼠标悬停在其上时的活动背景; tkinter.tk
按钮默认情况下不具有此功能。活动背景的真正含义是单击按钮时的背景颜色。尽管有多种方法可以使用tkinter.tk
来完成此操作,使用tkinter.ttk
轻松获得所需内容的简单方法。
import tkinter as tk
from tkinter import ttk
def vp_update_gui():
#'''Starting point when module is the main routine.'''
global val, w, root
#redalert_support.init(root, top)
root.update()
w = None
def destroy_Toplevel1():
global w
w.destroy()
w = None
class Toplevel1:
def __init__(self, top=None):
'''This class configures and populates the toplevel window.
top is the toplevel containing window.'''
_bgcolor = '#d9d9d9' # X11 color: 'gray85'
_fgcolor = '#000000' # X11 color: 'black'
_compcolor = '#d9d9d9' # X11 color: 'gray85'
_ana1color = '#d9d9d9' # X11 color: 'gray85'
_ana2color = '#ececec' # Closest X11 color: 'gray92'
font13 = "-family {Segoe UI} -size 22"
font14 = "-family {Segoe UI} -size 21"
top.geometry("480x300+267+205")
top.minsize(120, 1)
top.maxsize(1028, 749)
top.resizable(1, 1)
top.title("SecuriCode RedAlert")
top.configure(background="#4339fb")
s = ttk.Style()
s.configure('Kim.TButton', foreground='maroon',activeforeground="yellow")
self.Button1 = ttk.Button(top,style='Kim.TButton',text='''Clear Alarm''')
self.Button1.place(relx=0.333, rely=0.667, height=54, width=177)
self.Text1 = tk.Text(top)
self.Text1.place(relx=0.125, rely=0.133, relheight=0.423, relwidth=0.756)
self.Text1.configure(background="white")
self.Text1.configure(font=font13)
self.Text1.configure(foreground="black")
self.Text1.configure(highlightbackground="#d9d9d9")
self.Text1.configure(highlightcolor="black")
self.Text1.configure(insertbackground="black")
self.Text1.configure(selectbackground="#c4c4c4")
self.Text1.configure(selectforeground="black")
self.Text1.configure(wrap="word")
root = tk.Tk()
top = Toplevel1(root)
while 1:
vp_update_gui()
#Receive data from LAN device
reply = 's.recv(34)'
#Receive replies from SMS Gateway
#smsreply = g.recv(34)
#Check for Lan device keep alive replies
if reply == '-1':
#print 'Device alive'
print (reply)
#Check for valid Tag strings
if reply == '+1':
print ('Tag string received')
print (reply)
#Send SMS alert message
doorcode = reply[5:6]
doornumber = int(doorcode, 16)
#print doornumber
tagcode = reply[8:9]
tagnumber = int(tagcode, 16)
#print tagnumber
print( 'Alert Door ' +str(doornumber) + ' Tag ' +str(tagnumber) )
答案 1 :(得分:0)
通过在“异步模式”下运行PySimpleGUI程序,可以轻松解决“阻塞”问题。文档中有大量有关在读取调用中使用超时的信息,您将找到大量演示此技术的演示程序。
这是循环的示例代码,每100毫秒更新一次计数器。您可以为硬件条件或某些条件集添加轮询,而不是更新文本。在此处可以添加代码以轮询某些内容。
import PySimpleGUI as sg
layout = [ [sg.Text('My Window')],
[sg.Text('Will output here', key='-OUT-')],
[sg.Button('Exit')] ]
window = sg.Window('A non-blocking window', layout)
count = 0
while True:
event, values = window.read(timeout=100) # returns every 100 milliseconds
if event == sg.WIN_CLOSED or event == 'Exit':
break
window['-OUT-'].update(f'Count={count}')
count += 1
window.close()