2

I have a script which imports an tiff image from a location in my computer from inside a class:

from PIL import Image, ImageTk
import Tkinter

class Window(Tkinter.Tk):
    def __init__(self,parent):
        Tkinter.Tk.__init__(self,parent)
        self.parent = parent
        self.initialize()

    def initialize(self):    
        # More code here       
        self.photo = ImageTk.PhotoImage(Image.open('C:\Users\...\image\image.tif'), self)
        ImageLabel = Tkinter.Label(self, image=self.photo)
        ImageLabel.grid()
        # More code here 

When I package this script using PyInstaller the image is not packaged into the executable. I have searched around and I think the solution is to use the following function...

def resource_path(relative):
    if hasattr(sys, "_MEIPASS"):
        return os.path.join(sys._MEIPASS, relative)
    return os.path.join(relative)

...to generate the path to the file:

filename = 'image.tif'
filepath = resource_path(os.path.join(data_dir, filename)

I am not sure of where/how to use this function. Should I put it inside the class and call it like this?

from PIL import Image, ImageTk
import Tkinter

class Window(Tkinter.Tk):
    def __init__(self,parent):
        Tkinter.Tk.__init__(self,parent)
        self.parent = parent
        self.initialize()

    def initialize(self):    
        # More code here       
        filename = 'image.tif'
        data_dir = 'C:\Users\...\image'
        filepath = self.resource_path(os.path.join(data_dir, filename)
        self.photo = ImageTk.PhotoImage(Image.open(filepath), self)
        ImageLabel = Tkinter.Label(self, image=self.photo)
        ImageLabel.grid()
        # More code here    

    def resource_path(self, relative):
        if hasattr(sys, "_MEIPASS"):
            return os.path.join(sys._MEIPASS, relative)
        return os.path.join(relative)
John Crow
  • 927
  • 3
  • 13
  • 26

1 Answers1

1

So I still don't know how to use resource_path(), but the following code does the job I wanted:

from PIL import Image, ImageTk
import Tkinter

class Window(Tkinter.Tk):
    def __init__(self,parent):
        Tkinter.Tk.__init__(self,parent)
        self.parent = parent
        self.initialize()

    def initialize(self):    
        # See if running as script or executable and get path of the script/application
        if getattr(sys, 'frozen', False):
            application_path = os.path.dirname(sys.executable)
        elif __file__:
            application_path = os.path.dirname(__file__)
        # Join application path and relative file path
        filename = 'image.tif'
        pathtofile = os.path.join(application_path, filename)                     
        self.photo = ImageTk.PhotoImage(Image.open(pathtofile, self)
        ImageLabel = Tkinter.Label(self, image=self.photo)
        ImageLabel.grid()
John Crow
  • 927
  • 3
  • 13
  • 26
  • just realized you're OP and the person submitting answer. I kinda got `resource_path` working. But I morphed it into an IF statement, to check if i'm running as a compiled EXE or a .py file. Thanks for that bit on the `_MEIPASS` folder! I was stuck on that for a year now. see my answer regarding using a Selenium WebDriver https://stackoverflow.com/questions/47747516/pyinstaller-and-geckodriver-generate-issue-after-compile-to-exe/63696813#63696813 – Brian W Sep 01 '20 at 23:42