Не удается обновить изображения, меняющие контакты GPIO

Я пытаюсь создать программу, которая просто считывает 2 контакта, в данном случае контакт 17 и контакт 27, используя режим установки BCM. В зависимости от значения каждого вывода (0 или 1) программа покажет на экране другое изображение.

Моя проблема в том, что при первом запуске программы изображение, которое она показывает, является правильным, но если тем временем я устанавливаю какой-либо контакт в другое состояние (ВКЛ/ВЫКЛ), программа не загружает правильное изображение на экран, показывая мне сообщение об ошибке.

Если я просто пытаюсь запустить «отпечатки», все работает нормально, но с изображениями у меня всегда такая проблема. Я никогда не пропускаю сразу после первого изображения. Застрять с исходным изображением на всю программу. Я получаю сообщение об ошибке в create_image return self._create.

РЕДАКТИРОВАТЬ: Изображение сообщения об ошибке в ссылке ниже

я получаю ошибку https://i.imgur.com/50BxkFp.png

import Tkinter as tk
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setup(17,GPIO.IN)
GPIO.setup(27,GPIO.IN)
app = tk.Tk()
app.attributes("-fullscreen", True)
app.title('Presence State')
screen_width = app.winfo_screenwidth()
screen_height = app.winfo_screenheight()

emptyP = tk.PhotoImage(file = "./images/emptyPresence.jpg")
leftP = tk.PhotoImage(file = "./images/leftPresence.jpg")
rightP = tk.PhotoImage(file = "./images/rightPresence.jpg")
bothP = tk.PhotoImage(file = "./images/bothSidesPresence.jpg")

fname = tk.Canvas(app, bg = "black" , width = screen_width, height =
        screen_height)

def empty():
    image = fname.create_image(screen_width/2, screen_height/2, anchor =  
            tk.CENTER, image = emptyP)

def left():
    image = fname.create_image(screen_width/2, screen_height/2, anchor = 
            tk.CENTER, image = leftP)

def right():
    image = fname.create_image(screen_width/2, screen_height/2, anchor = 
            tk.CENTER, image = rightP)

def both():
    image = fname.create_image(screen_width/2, screen_height/2, anchor = 
            tk.CENTER, image = bothP)

while(1):
        if GPIO.input(17) == 0 and GPIO.input(27) == 0:
                empty()
                time.sleep(.5)
        elif GPIO.input(17) == 1 and GPIO.input(27) == 0:
                  left()
                  time.sleep(.5)
        elif GPIO.input(17) == 0 and GPIO.input(27) == 1:
                  right()
                  time.sleep(.5)
        else:
                  both()
                  time.sleep(.5)


        fname.pack()
        app.mainloop()

person nimohoxi    schedule 05.07.2019    source источник
comment
Поиск SO для «[tkinter] sleep» поможет. Также приложение будет добавлять изображение на холст два раза в секунду. Изображение нужно будет обновить/исправить, а не добавлять.   -  person Tls Chris    schedule 06.07.2019
comment
@TlsChris во-первых, спасибо за ваш ответ. Во-вторых, я не уверен, что это проблема, но я читал, что сон просто полностью застревает с любыми операциями, происходящими в фоновом режиме. Значит, если я поменяю булавки в то время, когда изображение отображается, он не будет читать булавки в это время, верно? В-третьих, я читал о том, как обновить изображение, и я находил решения, такие как fuction after или update_idletasks, но любой из этих двух функций требуется agr, чтобы вернуться к предыдущей функции. Но я не вижу, где я буду вспоминать в своей программе: S   -  person nimohoxi    schedule 08.07.2019


Ответы (1)


У меня нет RaspberryPi, поэтому я создал две контрольные кнопки для имитации контактов ввода-вывода. Я показал результат в этикетке. Изменение результата для отображения изображений не должно быть слишком сложным. Функция on_after вызывает себя каждые 500 миллисекунд вместо исходного сна (0,5) с.

import tkinter as tk
from tkinter import ttk

root = tk.Tk()
root.geometry('400x100')
root.title('"After" Demonstation')

# Set up fake GPIO Pins as Checkbuttons
# IntVars to easily read the state.
gpio17 = tk.IntVar()
gpio27 = tk.IntVar()
# Initialise to zero
gpio17.set(0)
gpio27.set(0)

ttk.Checkbutton(root, variable = gpio17, text = 'GPIO 17', width = 20).grid( row = 0, column = 0)
ttk.Checkbutton(root, variable = gpio27, text = 'GPIO 27', width = 20).grid( row = 0, column = 2)

# I'm using a label for simplicity. Amendments required 
# below to cope with images.
result = tk.StringVar()
ttk.Label(root, textvariable = result, width = 20 ).grid(row=1, column=1)

DELAY = 500 # in milliseconds

def on_after():
    """ Reads the state of the io pins and sets the result
        to the appropriate value. """
    # Code to fetch the IO states will be different with real pins. 
    io17 = gpio17.get()  # Get the button states
    io27 = gpio27.get()

    # Set the result. Will be different with images.
    if io17:
        if io27:
            result.set('Both')
        else:
            result.set('Left')
    else:
        if io27:
            result.set('Right')
        else:
            result.set('None')

    id = root.after( DELAY, on_after) # This implements the loop by calling on_after again.

id = root.after( 1, on_after) # Start the loop.

root.mainloop()
person Tls Chris    schedule 08.07.2019
comment
Большое спасибо @Tls Крис, который переделал мой код, превратив while (1) в функцию main и используя метод after (), отлично сработало и знаю, что я могу обновить изображения. Но у меня возникла новая проблема с контактами GPIO, но я, вероятно, должен задать вопрос в новом посте, так как это больше не связано с Tkinter. Но спасибо еще раз. Вы были очень полезны! - person nimohoxi; 10.07.2019