Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why not use pkgutil for resource loading? #269

Closed
D0m0 opened this issue Sep 11, 2022 · 7 comments
Closed

Why not use pkgutil for resource loading? #269

D0m0 opened this issue Sep 11, 2022 · 7 comments

Comments

@D0m0
Copy link

D0m0 commented Sep 11, 2022

Pygubu is an ingenious tool that I discovered only now, although I use tkinter for at least 2 years! It's a professionally developed solid piece of code. I tried it and it works as intended out of the box!

I often put my project in a zip file, rename it to .pyz, and it becomes a single-file cross-platform app (which often only needs python3 installed). To load resources in such an app I use pkgutil.get_data(), which is nice because it works both ways: from a pyz-file and from the original unpacked app while I debug it. And pkgutil is a standard library.

So, when I use Pygubu I can load .ui files using builder.add_from_string(pkgutil.get_data(PROJECT_MODULE, PROJECT_UI)), but if I use images inside the .ui file, they are not being loaded.

I understand that Pygubu is adapted for use with PyInstaller and several other packagers, but maybe using pkgutil.get_data() will simplify all this resource-loading? Or maybe I'm doing something wrong?

Thanks!

@alejandroautalan
Copy link
Owner

Hello @D0m0, thanks for trying pygubu. I'm glad that it is useful to you.

I will investigate pkgutil and find a solution for this case.

Regards
Alejandro A.

@alejandroautalan
Copy link
Owner

Hello @D0m0, can you provide a little example application so I can see how do you setup PROJECT_MODULE and PROJECT_UI variables?

Regards
Alejandro A.

@D0m0
Copy link
Author

D0m0 commented Sep 12, 2022

Hi! Here's my sample project:

project
├── __main__.py
├── dist
│   └── gubu.pyz        <--- zip, contains the whole project folder
└── ui
    ├── __init__.py
    ├── pygubu-test.ui  <--- contains references to *.gif
    ├── red.gif
    ├── green.gif
    └── yellow.gif

main.py

#!/usr/bin/env python3

from pkgutil import get_data
import pathlib
import tkinter as tk
from tkinter import messagebox
import tkinter.ttk as ttk
import pygubu

PROJECT_PATH = pathlib.Path(__file__).parent
PROJECT_UI = 'pygubu-test.ui'

class HelloWorldApp:
	def __init__(self, master=None):
		self.builder = builder = pygubu.Builder()
		builder.add_resource_path(PROJECT_PATH)
		builder.add_from_string(get_data('ui', PROJECT_UI))
		self.mainwindow = builder.get_object('toplevel1', master)
		builder.connect_callbacks(self)

	def on_button_browse_ac(self):
		messagebox.showinfo(title="Message", message="DhAJsja1!", parent=self.mainwindow)

if __name__ == '__main__':
	print(PROJECT_PATH)
	print(__file__)
	app = HelloWorldApp()
	app.mainwindow.mainloop()

@D0m0
Copy link
Author

D0m0 commented Sep 12, 2022

When I launch main.py, it works as expected, printing these values:

.                 # PROJECT_PATH
./__main__.py     # __file__

When I run dist/gubu.pyz, it works too (but without images), printing these values:

dist/gubu.pyz                 # PROJECT_PATH
dist/gubu.pyz/__main__.py     # __file__

gubu.pyz is a .zip file with a shebang header like this: #!/usr/bin/env python3
It works in Windows and Linux, as long as python3+tk is installed (I also put the pygubu folder in the zip file).

My theory is that using pkgutil.get_data() can extract resources in any case, maybe even when using PyInstaller etc. But I could be wrong, and I didn't test that. Tell me if you need help testing this.

@alejandroautalan
Copy link
Owner

Thanks. One more question, which python version are You using?

@D0m0
Copy link
Author

D0m0 commented Sep 13, 2022

I'm using versions 3.6.2, 3.7.5, 3.9. I don't mind if you ditch the oldest versions!

@alejandroautalan
Copy link
Owner

Hello @D0m0.

It seems that the recommended approach is to use the importlib.resources module.

I have been working with that in mind. I have created an example of use here.

If you can, test it with your projects installing pygubu from the github repositories with:

pip install git+https://github.com/alejandroautalan/pygubu git+https://github.com/alejandroautalan/pygubu-designer

If you have any suggestions let me know.

Regards
Alejandro A.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants