Включение и выключение отображения с графическим интерфейсом Tkinter на Raspberry Pi с помощью python3 - PullRequest
0 голосов
/ 12 октября 2018

Мне нужно включать и выключать дисплей, пока он включен, мне нужно, чтобы он отображал приветственное сообщение, созданное с помощью 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 ]

0 голосов
/ 12 октября 2018

Графический интерфейс Tkinter отображался после того, как я прервал программу, так как root.mainloop() был помещен в конец программы.

Понимание Tkinter mainloop Эта ссылка помогла мне понятьmainloop и внести необходимые изменения в набросок питона.

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()
0 голосов
/ 12 октября 2018

Вы попали в стандартную ловушку для приложений tkinter.У вас есть бесконечный цикл, который не позволяет обновлять графический интерфейс tkinter.Никогда не используйте бесконечный цикл с приложениями tkinter.Используйте только mainloop ()

Если вы хотите смешивать чтение GPIO с tkinter, вам нужно воспользоваться одним из следующих подходов

  1. Использовать метод .after tkinter для периодического планированиявызов функции.Эта функция читает с выводов GPIO и обновляет графический интерфейс на основе состояния GPIO.root.after(1000,do_function) вызовет функцию с именем do_function через 1000 миллисекунд.Если ваш do_function также содержит вызов метода .after, функция сама запланирует повторный вызов через указанный период.

  2. Использование обратных вызовов GPIO.Это намного проще, если вы используете библиотеку gpiozero вместо модуля RPi.GPIO, поскольку у вас есть доступный синтаксис button.when_pressed = do_function.

В любом из этих методовФункция, которая вызывается, будет в том месте, где вы добавите любой код для изменения GUI в зависимости от состояния выводов GPIO.

...