使用Python3在Raspberry Pi上通过Tkinter GUI打开和关闭显示器

3

我需要控制开关显示屏,同时在显示屏打开时,使用tkinter-python创建欢迎消息。

我编写的程序能够控制开关显示屏,但只有在退出程序后才会显示tkinter标签。

请问为什么在编译程序时tkinter标签没有被显示?

import sys
import os
import time
from tkinter import *
import tkinter as tk
from tkinter.font import Font
import RPi.GPIO as GPIO

#pin description
sensor = 11

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(sensor,GPIO.IN)

print("Initializing PIR sensor....")
time.sleep(12)
print("PIR ready")
print("")

#initializing tkinter parameters
root = tk.Tk()
text = tk.Text(root)
font1 = Font(family = 'Helvetica', size = 30, weight = 'bold')
font2 = Font(family = 'Helvetica', size = 20, weight = 'bold')
font3 = Font(family = 'Helvetica', size = 15, weight = 'bold')

explanation = """WELCOME TO MY GUI"""
colin = tk.PhotoImage(file="background.gif")
#background=tk.Label(root,compound = tk.CENTER, text=explanation,font=font1, image=colin).pack()

def exitProgram():
    print("Exit button pressed")
    GPIO.cleanup()
    root.quit()
    exitButton =tk.Button(root, text = "Exit", font = font3, command = exitProgram, height = 1, width = 4, bd =1)
    exitButton.place(x= 350, y =435)


root.attributes("-fullscreen",True)

if sys.platform.startswith('linux'):
    os.system("xset dpms force off")
else:
    os.system("xset dpms force on")

try:
    while True:
        i = GPIO.input(sensor)
        if i==1:
            background=tk.Label(root,compound = tk.CENTER, text=explanation,font=font1, image=colin).pack()
            print("Human presence detected")
            if sys.platform.startswith('linux'):
                #background = tk.Label(root, compound = tk.CENTER, text=explanation, font = font1,image=colin).pack()
                os.system("xset dpms force on")
            time.sleep(30)
        else:
            print("no human around")
            if sys.platform.startswith('linux'):
                os.system("xset dpms force off")
            time.sleep(5)

except KeyboardInterrupt:
    GPIO.cleanup()

root.mainloop()

如您所见,我正在使用传感器来检测任何动作。如果检测到动作,则屏幕会打开并显示欢迎消息。

您还会看到,在草稿的不同位置,我已经注释了相同的代码行。我尝试将背景标签放置在不同的位置,但仍然出现同样的问题。屏幕会打开和关闭,但tkinter标签只有在我退出程序后才会显示。

2个回答

1
您陷入了tkinter应用程序的标准陷阱。您有一个无限循环,它不允许tkinter GUI更新。永远不要在tkinter应用程序中使用无限循环。只使用mainloop()。
如果您想将GPIO读取与tkinter混合使用,则需要采取以下其中一种方法:
1. 使用.after tkinter方法定期安排函数调用。该函数从GPIO引脚读取并根据GPIO状态更新GUI。root.after(1000,do_function)将在1000毫秒后调用名为do_function的函数。如果您的do_function还包含对.after方法的调用,则该函数将安排自己在指定时间段后再次调用。 2. 使用GPIO回调。如果您使用gpiozero库而不是RPi.GPIO模块,则可以使用button.when_pressed = do_function语法,这样会更容易。
使用任何一种方法,被调用的函数将是您添加任何基于GPIO引脚状态更改GUI的代码的地方。

0

由于程序末尾放置了root.mainloop(),所以在我中断程序后,Tkinter GUI 仍然显示。

Tkinter 理解 mainloop 这个链接帮助我理解了 mainloop 并在 Python 草图中进行了必要的更改。

import sys
import os
import time
from tkinter import *
import tkinter as tk
from tkinter.font import Font
import RPi.GPIO as GPIO

#pin description
sensor = 11

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(sensor,GPIO.IN)

print("Initializing PIR sensor....")
time.sleep(12) #to warmup the sensor
print("PIR ready")
print("")

#initializing tkinter parameters
root = tk.Tk()
text = tk.Text(root)
font1 = Font(family = 'Helvetica', size = 30, weight = 'bold')
font2 = Font(family = 'Helvetica', size = 20, weight = 'bold')
font3 = Font(family = 'Helvetica', size = 15, weight = 'bold')

explanation = """WELCOME TO MY GUI"""
colin = tk.PhotoImage(file="background.gif")
background=tk.Label(root,compound = tk.CENTER, text=explanation,font=font1, image=colin).pack()

def exitProgram():
    print("Exit button pressed")
    GPIO.cleanup()
    root.quit()
exitButton =tk.Button(root, text = "Exit", font = font3, command = exitProgram, height = 1, width = 4, bd =1)
exitButton.place(x= 350, y =435)


root.attributes("-fullscreen",True)

os.system("xset dpms force off")
#keep the display turned off until any motion is detected

try:
    while True:
        i = GPIO.input(sensor)
        if i==1:#turn on the display when motion is detected
           print("Human presence detected")
           os.system("xset dpms force on")
           root.update()
           time.sleep(30)
       else:
           print("no human around")
           os.system("xset dpms force off")
           time.sleep(5)

except KeyboardInterrupt:
    GPIO.cleanup()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接