1

I have a package with the following structure:

package
├── LICENSE
├── README.md
├── MANIFEST.in
├── my_pkg
│   └── __init__.py
│   └── main.py
│   └── style.qss
├── setup.py

When I install it from github using pip, the stylesheet file style.qss is cloned, but when I launch the script typing foopkg it is not loaded. This is my setup.py file:

setup.py

import setuptools

with open("README.md", "r") as fh:
    long_description = fh.read()

setuptools.setup(
    name="my_pkg",
    version="0.0.1",
    author="foo",
    author_email="foo@mail.com",
    description="A small gui",
    long_description=long_description,
    long_description_content_type="text/markdown",
    # url="https://github.com/foo/pkg",
    include_package_data=True,
    packages=setuptools.find_packages(),
    install_requires=[
        'PyQt5',
    ],
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires='>=3.7',
    entry_points={
        "gui_scripts": [
            "foopkg = my_pkg.main:main",
        ]
    }
)

And this is my MANIFEST.in file:

MANIFEST.in

recursive-include my_pkg *.qss

The main.py is

main.py

import sys
    ...
def main():
    app = QApplication(sys.argv)
    style_path = sys.path[0] + '/style.qss'

    file = QFile(style_path)
    file.open(QFile.ReadOnly)
    stream = QTextStream(file.readAll())
    app.setStyleSheet(stream.readAll())

    gui = GuiWindow()
    gui.show()

    app.exec_()


if __name__ == '__main__':
    main()

What am I missing? What should I modify to be able to call my script using stylesheet?

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Gigioz
  • 367
  • 5
  • 19
  • What makes you think that style.qss should be automatically included? – musicamante Dec 18 '20 at 11:06
  • I naively thought that all the files in the package folder would be cloned – Gigioz Dec 18 '20 at 11:10
  • I would like to improve the answer because now, even though the stylesheet is cloned, the script which you can launch by typing "foopkg" doesn't find it. Any help is veeery appreciated. – Gigioz Dec 18 '20 at 11:11
  • 1
    1. Only files directly related to the main package script(s) are added (those explicitly declared in the imports of each script, recursively), everything else is not, and that's for good: a project directory could contain hundreds or thousands of files, even if only a few of them are actually used by the program. 2. If the answer doesn't actually solve the issue, you can delete it, then you can restore and edit it or create a new one as soon as you find the correct approach. – musicamante Dec 18 '20 at 11:30
  • @Gigioz show main.py – eyllanesc Dec 18 '20 at 14:50

1 Answers1

1

When you build routes you must take into account what information each part contains, for example sys.path[0] contains the information from where the application is launched, for example when launching the entrypoint in Linux in my case it is /usr/bin. Instead you should use the __file__ attribute:

import os


CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))

def main():
    app = QApplication(sys.argv)
    style_path = os.path.join(CURRENT_DIR, 'style.qss')

    file = QFile(style_path)
    # ...
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Please, do not recommend the unreliable use of `__file__` for accessing package data. There is now [_`importlib.metadata`_ in the standard library](https://docs.python.org/3/library/importlib.metadata.html) (+ the [_`importlib_metadata`_ backport](https://pypi.org/project/importlib-metadata/)). And before that, we already had [_setuptools_' _`pkg_resources`_](https://setuptools.readthedocs.io/en/latest/pkg_resources.html). – sinoroc Dec 20 '20 at 17:21
  • @sinoroc You have just pointed out an option, but my question is because my solution is not correct so that I can analyze if my answer is incorrect and then correct it or at least give a warning. That there is an alternative does not imply that the other options are not valid. – eyllanesc Dec 20 '20 at 17:23
  • @sinoroc I will understand you if another application wants to access the files of the library, but this is not the case since the library will access its own files – eyllanesc Dec 20 '20 at 17:28
  • Relying on the value of `__file__` will break in some cases. For example when executing directly from a zipped archive. Think `zipapp` for example. This does not matter if it is the library accessing its own files or not. This is a serious concern, not just about a choice. Relying on `__file__` will break. – sinoroc Dec 20 '20 at 19:04
  • Oh... Apologies, I meant [`importlib.resources`](https://docs.python.org/3/library/importlib.html#module-importlib.resources) and the backport [`importlib-resources`](https://pypi.org/project/importlib-resources/) of course, not `importlib.metadata`. – sinoroc Dec 20 '20 at 19:11
  • @sinoroc Let me analyze the case of zipapp, if my solution breaks in that case then I will place your solution. – eyllanesc Dec 20 '20 at 19:13
  • Sadly I can not find one good article or answer that clearly and cleanly explains, it is all a bit scattered around. The best I can cite right now is this: https://stackoverflow.com/q/6028000 there are some bits in this page that somehow back up this issue. – sinoroc Dec 20 '20 at 19:15
  • 1
    @sinoroc It is clearly a duplicate that I would not have found so I closed the question. – eyllanesc Dec 20 '20 at 19:18