Проблема PIL, но только при вызове из другого объекта (изображение не существует) - PullRequest
0 голосов
/ 19 апреля 2019

Я пытаюсь разработать приложение Python для RaspberryPi на ПК.Чтобы протестировать один аспект, я написал объектный класс для эмуляции устройства отображения OLED (аппаратного обеспечения), которое ПК не может использовать (без I2C).Класс Wdisp просто загружается вместо драйвера оборудования при использовании ПК.

У меня есть другой класс, который объединяет несколько необходимых мне OLED-функций (писать текст, рисовать индикатор выполнения и т. Д.)

# OLED display object


import os
Win = False

if os.name == 'nt':
    Win=True
    from WindowsOLED import Wdisp    
else:
    import Adafruit_GPIO.SPI as SPI
    import Adafruit_SSD1306

from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont

class OLEDDisplay(object):

    def __init__(self):

        # Raspberry Pi pin configuration:
        RST = 24

        if Win:
            self.disp = Wdisp()
        else:
            self.disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST)

        # Initialize library.
        self.disp.begin()

        # Create blank image for drawing.

        self.width = 128 #self.disp.width
        self.height = 64 #self.disp.height
        self._image = Image.new('1', (self.width, self.height))
        self.draw = ImageDraw.Draw(self._image)
        # Load default font.
        self.font = ImageFont.load_default()
        self.clear()

    def __del__(self):
        self.clear()

    def __repr__(self):
        return 'OLED display object for SSD1306 I2C'

    def clear(self):
        # Clear display
        self.disp.clear()
        self.disp.display()

    def write(self, text):

        self.draw.text((0, 2),    text,  font=self.font, fill=255)
        self._show()

    def progressbar(self, percent):
        #draw a progress bar on top half of screen
        shape_width = self.width * (percent/100)
        padding =2
        top = padding
        bottom = (self.height/2) - padding
        x = padding
        self.draw.rectangle((x, top, self.width-padding, bottom), outline=255, fill=0)
        self.draw.rectangle((x, top, x+shape_width, bottom), outline=255, fill=255)
        self._show()

    def loadimage(self, imagefile):
        #open, convert and display an image
        self._image = Image.open(imagefile).resize((self.disp.width,
                                                   self.disp.height),
                                             Image.ANTIALIAS).convert('1')
        self._show()

    def _show(self):
        # Display image.
        self.disp.image(self._image)
        self.disp.display()

Если я тестирую этот класс в командной строке

Пример:

>>> from OLEDDisplay import*
>>> OD = OLEDDisplay()
>>> OD.progressbar(50) 

Работает нормально - объект OLEDDisplay рисуетв объекте изображения PIL передает изображение в объект Wdisp, а объект Wdisp преобразует изображение в BitMapImage и отображает его на Tkinter Label (self.L).

#Windows subsitute OLED display class
#displays a label image for testing 

from tkinter import  *
from PIL import Image, ImageTk
from tkinter import filedialog, messagebox
from tkinter.constants import *

class Wdisp(object):
    i=None
    width = 128
    height =64
    _image = None

    def __init__(self):
        self.master = Tk()
        self._image = Image.new('1', (self.width, self.height))
        self.i = ImageTk.PhotoImage(self._image)
        self.L= Label(self.master, text="label place holder", image=self.i)
        self.L.pack(expand=YES, fill=BOTH)

    def begin(self):
        pass


    def image(self, newimage):
        self._image = newimage

    def display(self):
        #display the image
        self.i = ImageTk.BitmapImage(self._image)
        self.L.config(image=self.i)

Однако, если я использую это в своем приложении или протестирую в небольшом приложении:

из tkinter import *

from PIL import Image, ImageTk
from tkinter import filedialog, messagebox
from tkinter.constants import *
from OLEDDisplay import*

def updateOLED():
    text = E.get
    print(text)
    OD.write(text)


master = Tk()

OD = OLEDDisplay()

E = Entry(master)
B = Button(master, text="update OLED", command = updateOLED)
E.pack()
B.pack()

Не удается с tkinter.TclError: image "pyimage4"не существует:

Traceback (most recent call last):
  File "D:\My Documents\PI Projects\Pyprojects\PTPIC\OLEDDisplay test.py", line 19, in <module>
    OD = OLEDDisplay()
  File "D:\My Documents\PI Projects\Pyprojects\PTPIC\OLEDDisplay.py", line 42, in __init__
    self.clear()
  File "D:\My Documents\PI Projects\Pyprojects\PTPIC\OLEDDisplay.py", line 52, in clear
    self.disp.clear()
  File "D:\My Documents\PI Projects\Pyprojects\PTPIC\WindowsOLED.py", line 45, in clear
    self.display()
  File "D:\My Documents\PI Projects\Pyprojects\PTPIC\WindowsOLED.py", line 36, in display
    self.L.config(image=self.i)
  File "C:\Python34\lib\tkinter\__init__.py", line 1324, in configure
    return self._configure('configure', cnf, kw)
  File "C:\Python34\lib\tkinter\__init__.py", line 1315, in _configure
    self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: image "pyimage4" doesn't exist

Понятия не имею, почему: возможно, переменная область действия?возможно, что-то странное с PIL, поэтому любые предложения приветствуются.

Cheers Bill

...