окна tkinter не исчезают после разрушения - PullRequest
0 голосов
/ 03 декабря 2018

Я пишу скрипт на Python для отображения изображений, воспроизведения музыки и показа видео на Raspberry Pi при срабатывании входов.Пока я работал над этим проектом, я решил добавить веб-камеру в сценарий.Я играл с различными стримерами веб-камеры, пока не нашел MPlayer, который, казалось, имел самую высокую частоту кадров и использовал наименьшее количество ресурсов.проблема заключалась в том, что графический интерфейс MPlayer был скрыт за окнами tkinter, которые я использовал для отображения изображений.Я попытался сделать несколько разных вещей, чтобы вывести окно MPlayer на передний план и заставить окна tkinter исчезнуть, но ничего не получалось.Вот мой код:

import sys
import os
import time
import subprocess
import RPi.GPIO as GPIO
if sys.version_info[0] == 2:
    import Tkinter
    tkinter = Tkinter
else:
    import tkinter
from PIL import Image, ImageTk
import board
import neopixel

x=1
GPIO.setmode(GPIO.BCM)
pixels = neopixel.NeoPixel(board.D10, 38)
pixels.fill((0, 0, 0))
GPIO.setwarnings(False)
GPIO.setup(17,GPIO.OUT)
GPIO.setup(18,GPIO.OUT)
GPIO.setup(27,GPIO.OUT)
GPIO.setup(22,GPIO.OUT)
GPIO.setup(24,GPIO.OUT)
GPIO.setup(25,GPIO.OUT)
GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(4, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.output(17,GPIO.LOW)
GPIO.output(18,GPIO.LOW)
GPIO.output(27,GPIO.LOW)
GPIO.output(22,GPIO.LOW)
GPIO.output(24,GPIO.LOW)
GPIO.output(25,GPIO.LOW)

def showPIL(pilImage, exVar = 0):
    try:
        root.withdraw()
        root.destroy()
        root.update()
    except:
        pass
    root = tkinter.Toplevel()
    if x == 1:
        w, h = root.winfo_screenwidth(), root.winfo_screenheight()
    else:
        w, h = 100, 100
    root.overrideredirect(1)
    root.geometry("%dx%d+0+0" % (w, h))
    #root.focus_set()
    root.bind("<Escape>", lambda e: (e.widget.withdraw(), e.widget.quit()))
    canvas = tkinter.Canvas(root,width=w,height=h)
    canvas.pack()
    canvas.configure(background='black')
    imgWidth, imgHeight = pilImage.size
    if imgWidth > w or imgHeight > h:
        ratio = min(w/imgWidth, h/imgHeight)
        imgWidth = int(imgWidth*ratio)
        imgHeight = int(imgHeight*ratio)
        pilImage = pilImage.resize((imgWidth,imgHeight), Image.ANTIALIAS)
    image = ImageTk.PhotoImage(pilImage)
    imagesprite = canvas.create_image(w/2,h/2,image=image)
    root.update()

showPIL(Image.open("Data/blank.png"))
while not GPIO.input(4):
    pass
music = subprocess.Popen(['cvlc', '/home/pi/Desktop/Data/music.mp3'])
showPIL(Image.open("Data/trophy.png"))
time.sleep(1)
GPIO.output(22,GPIO.HIGH)
time.sleep(0.5)
GPIO.output(27,GPIO.HIGH)
time.sleep(0.5)
GPIO.output(18,GPIO.HIGH)
time.sleep(0.5)
GPIO.output(17,GPIO.HIGH)
time.sleep(1)
showPIL(Image.open("Data/poison.png"))
pixels.fill((0, 255, 0))
os.system("pkill tk")
x=0
showPIL(Image.open("Data/blank.png"))
x=1
camera = subprocess.Popen(['mplayer', '-fs', 'tv://'])
os.system("wmctrl -a MPlayer")
time.sleep(8)
camera.kill()
os.system("omxplayer -b '/home/pi/Desktop/Data/movie.mp4'")
showPIL(Image.open("Data/gun.png"))
GPIO.output(24,GPIO.HIGH)
GPIO.output(25,GPIO.HIGH)
while not GPIO.input(23):
    pass
pixels.fill((0, 0, 0))
showPIL(Image.open("Data/dumbell.png"))
time.sleep(1)
showPIL(Image.open("Data/pipe.png"))
time.sleep(1)
showPIL(Image.open("Data/noose.png"))
time.sleep(1)
music.kill()
showPIL(Image.open("Data/blank.png"))
end = subprocess.Popen(['cvlc', '/home/pi/Desktop/Data/end.wav'])
time.sleep(8)
end.kill()

1 Ответ

0 голосов
/ 03 декабря 2018

Хорошо, поэтому здесь есть несколько ключевых проблем.

Одной из серьезных проблем является ваше try/except утверждение.

Ваша попытка, кроме как всегда, будет делать pass.Никогда не наступит время, когда вы сможете destroy() что-то и затем позвонить update().Это всегда будет приводить к ошибке, и поэтому будет выполняться оператор кроме pass.

Далее root = tkinter.Toplevel() является проблемой.Поскольку вы никогда не определяете экземпляр tkinter или то, что root должно быть, вы вместо этого создаете окно верхнего уровня, и это приведет к открытию экземпляра tkinter, но без имени переменной для работы.Указанный корень здесь определяется только локально для функции, и, таким образом, каждый раз, когда функция вызывается снова, нет записи о корне, которую функция пытается уничтожить, потому что она еще не была создана, насколько функция знает.Вам нужно будет определить свой корень как переменную global для чего-то подобного.

Даже если это работает для вас, должно быть 2 проблемы.Одним из них является дополнительное пустое окно, которое отображается вверху, и 2 - это окно не закрывается само по себе, когда вы закрываете окно верхнего уровня.

Затем вы пытаетесь использовать sleep при запуске экземпляра tkinter.Эти вещи несовместимы без использования многопоточности, поэтому вам нужно либо заняться многопоточностью, либо предпочтительнее узнать, как использовать after().After() - это то, как tkinter управляет синхронизированными событиями.

Вместо использования Toplevel() здесь необходимо использовать Tk().Вместо того, чтобы разрушать и перестраивать ваш графический интерфейс каждый раз, вы должны просто обновить окно.Продолжая суть того, что вы пытаетесь сделать, вы, вероятно, должны немного поэкспериментировать с tkinter и узнать, как работает менеджер событий, прежде чем пытаться реализовать проект raspberry pi.После того, как вы получите проданное представление о графическом интерфейсе Tkinter и его процессе, основанном на событиях, вы сможете делать более сложные вещи проще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...