Как закрыть уже показанное изображение и показать другое? - PullRequest
0 голосов
/ 28 января 2019

Я создаю программное обеспечение, которое при получении сигнала кнопки отображает изображение, а через 1 секунду отображается другое.Проблема в том, что я не знаю, как закрыть изображение, если оно уже было показано в полноэкранном режиме, предполагается, что Esc закрывается, но оно не работает.

import sys
import RPi.GPIO as GPIO 
import time 

pulse = 16
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

GPIO.setup(pulse, GPIO.IN, GPIO.PUD_UP) 

if sys.version_info[0] == 2:  
    import Tkinter
    tkinter = Tkinter 
else:
    import tkinter
from PIL import Image, ImageTk

blackImage = Image.open("black.png")
pattern = Image.open("pattern.jpg")

def showImage(nimage):
    root = tkinter.Tk()
    w, h = root.winfo_screenwidth(), root.winfo_screenheight()
    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 = nimage.size
    if imgWidth > w or imgHeight > h:
        ratio = min(w/imgWidth, h/imgHeight)
        imgWidth = int(imgWidth*ratio)
        imgHeight = int(imgHeight*ratio)
        nimage = nimage.resize((imgWidth,imgHeight), Image.ANTIALIAS)
    image = ImageTk.PhotoImage(nimage)
    imagesprite = canvas.create_image(w/2,h/2,image=image)
    root.mainloop()


while True:

    if GPIO.input(pulse) == False:
        time.sleep(0.1)
        print ("Shoot")
        showImage(blackImage)
        time.sleep(1)
        showImage(pattern)

В результате этого при нажатии кнопки на экране будет отображаться черное изображение, а затем изображение рисунка, но будет отображаться только черное изображение, и когда второе изображение не будет заменено изображениемшаблон, он не будет закрыт в то же время.нажмите Esc , я должен нажать Alt + F4 .

1 Ответ

0 голосов
/ 30 января 2019

GUI-программирование - это пользователь управляемый событиями , что означает, что правила для программирования отличаются от очень распространенного программирования на функциональном уровне, к которому вы, вероятно, привыкли.Ссылка в комментарии @ stovfl помогает понять разницу, поэтому я предлагаю вам прочитать то, что она говорит.

Чтобы понять, как это влияет на то, как все делается, ниже приведена попытка преобразовать ваш код в эту парадигму.,Также обратите внимание, что, поскольку у меня нет Raspberry Pi, код также (условно) связывает функцию обратного вызова обработчика событий с событиями левой кнопки мыши, чтобы имитировать их наличие, поэтому не стесняйтесь удалять этот материал, если хотите, учитывая, чтовы делаете.

Я пытался как можно больше инкапсулировать то, что необходимо сделать в одном «приложении» class, потому что это делает кодирование немного чище, уменьшая необходимость использованиякуча глобальных переменных.

from PIL import Image, ImageTk
try:
    import tkinter as tk  # Python 3
except ModuleNotFoundError:
    import Tkinter as tk  # Python 2

try:
    import RPi.GPIO as GPIO
except ModuleNotFoundError:
    GPIO_present = False  # No Raspberry Pi
else:
    GPIO_present = True
    GPIO_PULSE = 16  # Button channel.
    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)
    GPIO.setup(GPIO_PULSE, GPIO.IN, GPIO.PUD_UP)


class Application(tk.Frame):
    DELAY = 100  # ms

    def __init__(self, master=None):
        super().__init__(master)
        self.pack()
        self.w, self.h = self.winfo_screenwidth(), self.winfo_screenheight() # Fullscreen
        self.create_widgets()
        self.flag = False  # Initialize button clicked flag.
        self.after(self.DELAY, self.check_signal)  # Start background polling.

    def create_widgets(self):
        self.canvas = tk.Canvas(root, width=self.w, height=self.h, background='black')
        self.canvas.pack()

        pil_img = Image.open("black.png")

    def _load_image(self, filename):
        """ Use PIL to load (and resize if necessary) an image. """
        pil_img = Image.open(filename)
        img_width, img_height = pil_img.size

        if img_width > self.w or img_height > self.h:  # Too big?
            ratio = min(self.w/img_width, self.h/img_height)
            img_width, img_height = int(img_width*ratio), int(img_height*ratio)
            pil_img = pil_img.resize((img_width, img_height), Image.ANTIALIAS)  # Resize.

        img = ImageTk.PhotoImage(pil_img)  # Convert to tkinter PhotoImage.
        return img

    def create_widgets(self):
        self.canvas = tk.Canvas(root, width=self.w, height=self.h, background='black')
        self.canvas.pack()

        self.black_img = self._load_image("black.png")
        self.pattern_img = self._load_image("pattern.png")

        # Create a canvas image object place-holder for show_image() to update.
        self.image_id = self.canvas.create_image(self.w/2, self.h/2, image=None)

    def show_image(self, img):
        self.cur_img = img
        self.canvas.itemconfigure(self.image_id, image=self.cur_img)

    def show_next_image(self):
        self.after(100)  # Pause 0.1 second - avoid using time.sleep()
        print("Shoot")
        self.show_image(self.black_img)
        self.after(1000)  # Pause 1 second - avoid using time.sleep()
        self.show_image(self.pattern_img)

    def update_flag(self, e):
        """ Mouse left-button clicked handler. """
        self.flag = True

    def check_signal(self):
        if GPIO_present:
            self.flag = not GPIO.input(GPIO_PULSE)
        else:
            pass  # Assume something else is keeping self.flag updated.

        if self.flag:
            self.show_next_image()
            self.flag = False  # Reset

        root.after(self.DELAY, self.check_signal)  # Check again after delay.

if __name__ == '__main__':

    root = tk.Tk()
    w, h = root.winfo_screenwidth(), root.winfo_screenheight()
    root.overrideredirect(True)
    root.geometry("%dx%d+0+0" % (w, h))  # Fullscreen
    root.focus_set()
    root.bind("<Escape>", lambda e: e.widget.quit())

    app = Application(root)

    if not GPIO_present:
        # Using left mouse-button as substitute for GPIO.
        # Bind left mouse button click event handler.
        root.bind("<Button-1>", app.update_flag)

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