pyinstaller "could not parse stylesheet" - python-3.x

I'm building a small program using pyQt and pyInstaller.
I've tried to add an background image to my QMainWindow:
class pyPrimaMainWindow(QMainWindow):
def __init__(self):
...do some stuff...
self.setWindowIcon(QIcon(os.path.join(self.py_prima.resource_path(), "TH.ico"))) # <- this works
self.setStyleSheet("QMainWindow{{border-image: url({0});background-size:100%;}}".format(os.path.join(self.py_prima.resource_path(), "bg.png")))
The resource_path() methods looks like that:
def resource_path(self):
""" Get absolute path to resource, works for dev and for PyInstaller """
# PyInstaller creates a temp folder and stores path in _MEIPASS
base_path = getattr(sys, '_MEIPASS', "C:/Users/Tobias/eclipse/workspace/PyPrima/data/")
# except Exception:
# base_path =
print(base_path)
return base_path
It's copied from the pyinstaller wiki, returns an absoulte path and works for other pictures/icons.
However, if I build an executable with pyInstaller, the programm runs nice, but the background image is missing. Instead, the console outputs
"could not parse stylesheet of object ..."
If I run the python file, it works all fine...
Any ideas on this?
Thanks!

I'll answer my own question just in case someone else stumbles upon the same problem.
The fileseparators are wrong...
Fix it with
bgpath = os.path.join(self.py_prima.resource_path(), "bg.png")
bgpath = bgpath.replace("\\", "/")
self.setStyleSheet("QMainWindow{{border-image: url({0});background-size: 100%;}}".format(
bgpath))

Related

Python class cannot open file when object is created from directory below

I have a app.py file which is using a custom class which I created one level below, ie.
from myfolder import util_file
def get_data():
dataContainer = util_file.MyDataContainer()
# do more stuff
One folder down my util_file I create MyDataContainer as a class that uses data from two local files to instantiate itself. ie.
class MyDataContainer:
def __init__(self):
with open('file1.txt', 'r'):
#get needed init data part 1
#repeat operation with data in file2.txt
The object is created fine when I run from the file itself, ie.
if __name__ == '__main__':
testcont = MyDataContainer()
The issue is that when I run the code in app.py I get:
FileNotFoundError: [Errno 2] No such file or directory: 'file1.txt'
thrown at the line
with open('file1.txt', 'r'):
I am guessing that python is unable to see the file1.txt and file2.txt since it is in another directory at runtime but I checked the my path and the subfolder is in sys.path at runtime, so I believe these should be visible. I really do not understand what is going on here. Is there a different reason python is unable to see these files?

Acessing myclass defined in python file in different folder from jupyter notebook

I have following folder structure
|
|---notebook
| |
| --- MyNoteBook.ipnyb
|
|---python
| |
| --- image_rotation_utils.py
I have following content in python.image_rotation_utils.py
class ImageRotationUtils:
""" Utils for rotating images."""
def __init__(self, image_path=None, image_name=None, output_path=None, output_annotations_file=None ):
""" Initializes the class.
Args:
image_path: the relative path to the image
image_name: image file name
output_path: the relative path where rotated output file is stored.
output_annotations_file: annotations file where rotated anotations are stored.
"""
self.image_path = image_path
self.image_name = image_name
self.output_path = output_path
self.output_annotations_file = output_annotations_file
#other functions defined
Now in MyNoteBook.ipnyb I have following cells
Cell 1:
import sys
sys.path.insert(0, '..')
from python.image_rotation_utils import *
Above is executed successfully now in cell 2 I have below
myUtils = ImageRotationUtils()
I have getting below error
----> 1 ImageRotationUtils()
TypeError: __init__() missing 4 required positional arguments: 'image_path', 'image_name', 'output_path', and 'output_annotations_file'
whye I am getting this error when I have default values in constructor has None in class definition.
I am new to python and trying to put code in productive manner. What mistake I am making. Kindly provide inputs
What you pasted looks ok to me, and your code works for me without errors.
Perhaps something before or after that code is what is spoiling the class definition?
Perhaps you are running this in Jupyter or in IPython and you imported ImageRotationUtils previously, but then changed the code, and tried to reimport again -- and something was wrong with the new reimport so your definition did not get over-written? If that's the case, restart the environment (or the kernel in Jupyter) and rerun the code.
I would suggest putting a simple initialization code, like that constructor line, into the same source file and executing it as a separate process to test if that is the code or the environment issue.
As a matter of convenience and to avoid tweaking sys.path in your code, I would suggest adding your python directory to the PYTHONPATH environment variable before you load your environment, so you can just import.

How to pass optionparser arguments through pylint?

test.py
from optparse import OptionParser
class Test(object):
def __init__(self):
pass
def _test1(self, some_val):
print(some_val)
def main(self, some_val):
self._test1(some_val)
if __name__ == "__main__":
parser = OptionParser()
parser.add_option("-a", "--abcd", dest="abcd", default=None,help="some_val")
(options, args) = parser.parse_args()
val = options.abcd
mainobj = Test()
mainobj.main(val)
Above script works, when executed python test.py --abcd=wxyz
When I run python -m pylint test.py --abcd=wxyz , doesn't execute.
Error:
strong text Usage: __main__.py [options]
__main__.py: error: no such option: --abcd
How to execute through pylint ?
Can you please help me ?
You cannot send new arguments like that using Pylint
Pylint is a static code analysis tool. It does NOT run your program. Therefore it does not matter what arguments are sent to the main program you want to test. Imagine it tests your code as it was "text" without running it.
Also the syntax you are using in the command line is not right, because after-m pylint the arguments which are sent are actually Pylint's arguments. Pylint has it's own set of options and rules you can set. you can view a summary here
or just type in your command line this:
pylint --help
The error message you get is a Pylint error. if you want to change the options you insert to Pylint you would have to change its source code i reckon...
Hope I understood your question correctly and that it helps.

DLL problem after compile with cx_freeze when I use win32wnet importation

I create a script that connect to network folder with specific username and password that I don't give to user. This script connecto to network folder for 1 or 2 secondes, do stuff and disconnect after that to be sure user can't access network folder after that.
I work fine in my developpement environment.
I user cx_Freeze to convert my .py to .exe ( I use it for other little program many times )
Problem is that the .exe file works fine only on the same PC where I develop my app. On all other PC it give me error : File " network.py" line 1, in ImportError: DLL load failed: Le module spécifié est introuvable ( in english, it can't find the specified module )
I try to add DLL of win32wnet. but not working.
What I do wrong.
See my code and my import code
'''
import win32wnet
import os
import re
# configure initial parameter
shareFolder = "\\\\ultra\\circuit-bgo"
usager = "foo"
motPasse = "foo"
# use win32wnet to create resorce to connect or disconnect
net_resource = win32wnet.NETRESOURCE()
net_resource.lpRemoteName = shareFolder
# try to disconnect to be sure no connection steel exist
try:
win32wnet.WNetCancelConnection2(net_resource.lpRemoteName,0,0)
except:
pass
# create connection to network folder
laConnection = win32wnet.WNetAddConnection2(net_resource, motPasse, usager, 0)
if os.path.exists(net_resource.lpRemoteName):
print("connection réussi")
# do some stuff, like read write and modify some files ( 1 or 2 secondes )
else:
print("connection ÉCHOUÉ")
# opps, connection failed
# disconnect to the network folder. I don't want user can access the folder by itself
try:
win32wnet.WNetCancelConnection2(net_resource.lpRemoteName,0,0)
except:
pass
'''
Import code with cx_freeze
'''
import os
import sys
from cx_Freeze import setup, Executable
base = None
if sys.platform == 'win32':
base = 'Win32GUI'
#syspath = "c:\\Python32\\Lib\\site-packages\\win32\\perfmondata.dll"
buildOptions = dict(
packages=['win32wnet'],
excludes=[],
include_files=['perfmondata.dll',]
)
executables = [Executable('network.py', base=base)]
setup(name='TestNetwork',
version='0.1',
options=dict(build_exe=buildOptions),
description='NetWork',
executables=executables
)
'''
and I try the basic code when I normaly compile with cx_freeze
this is a batch file:
cxfreeze.bat "c:/Python32/Scripts/network.py" --base-name=Win32GUI --target-dir C:/Python32/Scripts/Dist_Network --icon c:/Python32/Scripts/Logo.ico
After many, many, many test and reinstallation of python and module I need to find DLL that give me problem. I found that 3 DLL files have to be copy to the same folder of my new .exe file ( program ). The 3 DLL files are : pythoncom32.dll, pythoncomloader32.dll and pywintypes32.dll You can find this files on c:\Windows\syswow64 or system32 depend of your python installation (32 bit or 64 bit)
If you have bether solution, you can add it.
Thanks

os.path.isfile fails when using sys.path.append

I have the following:
application/3rdPArtyApp/file.py
application/3rdPArtyApp/directory/someFile
application/MyApp/file.py
I want to access files from 3rdPArtyApp from MyApp so I do the following in MyApp/file.py
sys.path.append('../3rdPArtyApp')
This works fine and I can now access the files and functions by importing them.
However, there is a file in 3rdPartyApp that attempts to access a file inside a folder directory/someFile.
It uses the following to check if its a file which fails whenever its called from MyApp but doesn't fail when its called stand alone from 3rdPartyApp.
os.path.isfile(file)
I am assuming if fails when called from MyApp because its expecting it to beunder MyApp path.
How can I solve this issue?
If you cannot change the library code, I think you are stuck with having to change the working directory before every call.
I therefore implemented this function-like helper class change_cwd. Just wrap every function call to the external library with with change_cwd('../3rdPArtyApp'):.
import os
class change_cwd:
def __init__(self, path):
self.path = os.path.abspath(path)
def __enter__(self):
self.old_cwd = os.getcwd()
os.chdir(self.path)
def __exit__(self, exc_type, exc_value, traceback):
os.chdir(self.old_cwd)
print(os.getcwd())
with change_cwd('Downloads'):
print(os.getcwd())
print(os.getcwd())
/home/<user>
/home/<user>/Downloads
/home/<user>

Resources