Python 2.7 single executable for python kivy GUI with PyInstaller - python

I am trying unsuccessfully to wrap up my kivy GUI application into a single executable with pyinstaller. Whey I run PyInstaller, it creates a single executable, but when I run it I get a "fatal error" saying "Failed to execute script myApp". I am using python 2.7 on windows. Here is my directory setup:
GUI_DEV\
-myApp_style.kv (this is my kivy file)
-myApp.py (this is my main script)
-ico.ico (this is my icon file)
-myImage.png (this is an image used by myApp.py)
rel\
-myApp.spec (this is the spec file I am using with pyinstaller)
Here is my myApp.py code:
import kivy
#kivy.require("1.9.0")
from kivy.core.window import Window
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.properties import ObjectProperty
from kivy.lang import Builder
import sys, os
def resourcePath():
if hasattr(sys, '_MEIPASS'):
return os.path.join(sys._MEIPASS)
return os.path.join(os.path.abspath("."))
Builder.load_file('myApp.kv')
class designerLayout(GridLayout):
part = "123"
def update(self):
self.part = value
self.id_test.text = "hello world: "+str(self.part)
return
def spinner_clicked(self, value):
self.part = value
self.id_test.text = "hello world: "+str(self.part)
class myApp(App):
def build(self):
Window.clearcolor = (1,1,1,1)
Window.size = (930,780)
return designerLayout()
if __name__ == '__main__':
kivy.resources.resource_add_path(resourcePath()) # add this line
calcApp = myApp()
calcApp = myApp()
calcApp.run()
Here is my myApp.spec file:
# -*- mode: python -*-
from kivy.deps import sdl2, glew
block_cipher = None
a = Analysis(['..\\myApp.py'],
pathex=['C:\\GUI_DEV\\rel\\MyHiddenImports'],
binaries=None,
datas=None,
hiddenimports=['MyHiddenImports'],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
a.datas += [('myApp_style.kv', '../myApp_style.kv', 'DATA')]
exe = EXE(pyz, Tree('C:\\GUI_DEV\\','Data'),
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
*[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
name='myApp',
debug=False,
strip=False,
upx=True,
console=False, icon='C:\\GUI_DEV\\ico.ico' )
I am then running the command:
python -m PyInstaller myApp.spec
from the GUI_DEV\rel directory.
Any ideas as to why this is not working? I am not getting any errors that point me to any specific problems.

Related

How to generate .exe of a kivymd application without console properly?

I'm trying to generating a .exe of my kivymd code. I have coded a really simple code, because i was trying to learn how to do this.
My code is as follows:
from kivymd.app import MDApp
from kivymd.uix.label import MDLabel
from kivymd.uix.screen import Screen
class Demo(MDApp):
def build(self):
self.screen = Screen()
self.l1 = MDLabel(
text = "My Label"
)
self.screen.add_widget(self.l1)
return self.screen
if __name__ == "__main__":
Demo().run()
Really simple.
So i'm using a .spec like this:
# -*- mode: python ; coding: utf-8 -*-
import os
from kivy_deps import sdl2, glew
block_cipher = None
from kivymd import hooks_path as kivymd_hooks_path
current_path = os.path.abspath('.')
icon_path = os.path.join(current_path, 'imagens', 'icone.ico')
a = Analysis(['main.py'],
pathex=[current_path],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[kivymd_hooks_path],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
*[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
name='Eaton',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
icon=icon_path,
console=False )
My code file name is main.py and my .spec is main.spec.
So my problem is, when I use the console=True, this code and .spec works fine and create a good .exe, but when I use console=False the aplication returns error.
If someone can help me I will be very thankful.

Pyinstaller PyQt5 ModuleNotFoundError Second Window Won't Open

I am attempting to open a second GUI using PyQt5 and a second .py file - it works in the IDE but not when compiled as a single .exe. The first GUI opens, the second does not. I receive ModuleNotFoundError.
Traceback (most recent call last):
File "C:\Users\Me\PycharmProjects\ProjectName\dist\firstwindow\secondwindow.py", line 1, in <module>
import mysql.connector
ModuleNotFoundError: No module named 'mysql'
I have tried modifying the spec file in so many ways now that I can't even recall. From what I can tell, Pyinstaller has no issues importing modules from the first .py file, but when it attempts a second level import or hidden import on the secondwindow.py - it has issues.
I've tried pointing to the sql module in the pathex, datas and hidden imports fields of the spec file. I am entering text such as 'C:\\Users\\Me\\PycharmProjects\\ProjectName\\venv\\Lib\\site-packages\\mysql' into all three of these fields and still receiving the same error.
I have tried using --hiddenimport=mysql as in: pyinstaller --onefile --hiddenimport=mysql test.spec
In the example below, I have imported mysql.connector and arbitrarily used it in the code. This is to demonstrate the error I am receiving in my actual program relating to mysql. If I remove mysql.connector or attempt to import PyQt5 beforehand, I still have errors relating to PyQt5.
Minimum Reproducible Code:
firstwindow.py
import mysql.connector
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton
import subprocess
import sys
db = mysql.connector.connect()
class FirstWindow(QMainWindow):
def __init__(self):
super().__init__()
self.button = QPushButton("Push for Window")
self.button.clicked.connect(self.show_new_window)
self.setCentralWidget(self.button)
def show_new_window(self, checked):
subprocess.Popen("secondwindow.py", shell=True)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = FirstWindow()
window.show()
sys.exit(app.exec_())
secondwindow.py
import mysql.connector
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton
import sys
db = mysql.connector.connect()
class NewWindow(QMainWindow):
def __init__(self):
super().__init__()
self.button = QPushButton("Second Window Opened")
self.setCentralWidget(self.button)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = NewWindow()
window.show()
sys.exit(app.exec_())
test.spec
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(['firstwindow.py', 'secondwindow.py'],
pathex=['C:\\Users\\Me\\PycharmProjects\\ProjectName', 'C:\\Users\\Me\\PycharmProjects\\ProjectName\\venv\\Lib\\site-packages\\mysql'],
binaries=[],
datas=[('firstwindow.py', '.'), ('secondwindow.py', '.'), ('C:\\Users\\Me\\PycharmProjects\\ProjectName\\venv\\Lib\\site-packages\\mysql', '.')],
hiddenimports=['C:\\Users\\Me\\PycharmProjects\\ProjectName\\venv\\Lib\\site-packages\\mysql'],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='firstwindow',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='firstwindow')
followed by: pyinstaller --onefile test.spec

Compiling Kivy application to Windows Executable

I have been fighting PyInstaller for the past week trying to get my application to compile into a single executable.
I've tried several different implementations with the .spec file, and of the many methods I try, I can either get it to compile into a single executable that crashes immediately on launch, doesn't launch at all, or it runs, but is extremely slow. Nothing compared to that of when I run it out of PyCharm.
I'm unsure if the slow run speeds is because of the compiler or what, but it takes roughly 1-2 seconds for the execution task to run when I run it through PyCharm, however when it is ran from the executable it takes about 30-35 seconds and the application hangs.
My application essentially takes some text from TextInput boxes, grabs the text values from them, does some SQL querying and then submits proper information to update / add entry information into an access database.
My latest .spec file is as follows:
# -*- mode: python -*-
import pyodbc
from datetime import date
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.popup import Popup
from kivy.uix.textinput import TextInput
from kivy.lang import Builder
from kivy.properties import BooleanProperty, ObjectProperty
from kivy.deps import sdl2, glew
block_cipher = None
a = Analysis(['DBInterfaceAssistant.py'],
pathex=['C:\\Python36-32'],
binaries=[],
datas=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
name='DBInterfaceAssistant',
debug=False,
strip=False,
upx=True,
runtime_tmpdir=None,
console=False )
The product of this is an application that doesn't launch, it attempts to load the application but crashes immediately.
---EDIT---
My Current build script is as follows:
# -*- mode: python -*-
import pyodbc
from datetime import date
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.popup import Popup
from kivy.uix.textinput import TextInput
from kivy.lang import Builder
from kivy.properties import BooleanProperty, ObjectProperty
from kivy.deps import sdl2, glew
from kivy.tools.packaging.pyinstaller_hooks import get_deps_minimal, get_deps_all, hookspath, runtime_hooks
block_cipher = None
a = Analysis(['DBInterfaceAssistant.py'],
pathex=['C:\\Python36-32'],
binaries=[],
datas=[],
hookspath=hookspath(),
runtime_hooks=runtime_hooks(),
** get_deps_all())
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
*[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
name='DBInterfaceAssistant',
debug=False,
strip=False,
upx=True,
runtime_tmpdir=None,
console=False )
You may use the example from the Kivy docs:
from kivy.tools.packaging.pyinstaller_hooks import get_deps_minimal, get_deps_all, hookspath, runtime_hooks
a = Analysis(['examples-path\\demo\\touchtracer\\main.py'],
...
hookspath=hookspath(),
runtime_hooks=runtime_hooks(),
...
**get_deps_all())
coll = COLLECT(exe, Tree('examples-path\\demo\\touchtracer\\'),
a.binaries,
a.zipfiles,
a.datas,
*[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
strip=False,
upx=True,
name='touchtracer')
https://kivy.org/docs/guide/packaging-windows.html#overwrite-win-hook

Packaging Kivy 1.9.10 app on Windows

I have been trying to package a Kivy app which runs perfectly from the .py file. I use the PyInstaller module to create the .exe file. The .exe file is created but it fails to open.
I have tried all I can, and I have gone through the Kivy documentation https://kivy.org/docs/guide/packaging-windows.html# .
I noticed that the .exe file worked when it is only kivy modules that are imported but wouldn't work when other libraries such as pandas are imported.
Any help would be appreciated.
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from tkinter.filedialog import askopenfilename
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.config import Config
import pandas as pd
import sqlite3
from kivy.properties import StringProperty
Config.set('graphics', 'resizable', '0')
Config.set('graphics', 'width', '800')
Config.set('graphics', 'height', '450')
def databasesetup(sharepoint,exchange,onedrivefaculty,onedrivestudent):
def sharepoint(filename):
def exchangecleanup(file):
def OD4Bclean(filename):
class Container(BoxLayout):
Message = StringProperty()
def Selectfile(self):
def Selectfilecsv(self):
def Cleandata(self):
""" This function cleans all the uploaded files and returns the cleaned dataframes """
def CreateDatabase(self):
def downloadfiles(self):
class MainApp(App):
def build(self):
self.title = 'Technology Support App for Office 365 adoption'
return Container()
if __name__ == "__main__":
app = MainApp()
app.run()
the .spec file
from kivy.deps import sdl2, glew
# -*- mode: python -*-
block_cipher = None
a = Analysis(['main.py'],
pathex=['D:\\Users\\bodea\\Documents\\desktop kivy app\\main'],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
exclude_binaries=True,
name='main',
debug=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,Tree('D:\\Users\\bodea\\Documents\\desktop kivy app\\main'),
a.binaries,
a.zipfiles,
a.datas,*[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
strip=False,
upx=True,
name='main')

kivy error: OSError: File data/fonts/Roboto-Regular.ttfs not found and also im on windows 8.1

"main.py"
from kivy.app import App
class WeatherApp(App):
pass
if __name__="__main__":
WeatherApp().run()
"weather.kv"
Label:
text: "hello world"
i am expecting a window with a black background and the words "hello world"
in the middle
For me I managed to solve
Editing the spec file like so:
# -*- mode: python ; coding: utf-8 -*-
from kivy_deps import sdl2, glew
block_cipher = None
a = Analysis(['hello.py'],
pathex=['C:\\Users\\<username>\\PycharmProjects\\<project_dir>'],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='hello',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
Tree('C:\\Users\\<username>\\PycharmProjects\\<project_dir>'),
a.binaries,
a.zipfiles,
a.datas,
*[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
strip=False,
upx=True,
upx_exclude=[],
name='hello')
by copying the kivymd dir C:\Users<username>\Anaconda3\envs<project_name>\Lib\site-packages\kivymd to your dist folder
Roboto-Regular.ttfs Not Found - Windows 8.1
Currently, in the Kivy config file, the default fonts used for widgets displaying any text defaults to [‘Roboto’, ‘data/fonts/Roboto-Regular.ttf’, ‘data/fonts/Roboto-Italic.ttf’, ‘data/fonts/Roboto-Bold.ttf’, ‘data/fonts/Roboto-BoldItalic.ttf’].
The latest version of Roboto can be found at https://github.com/google/roboto/releases
There is a typo error and indentation problem in your app. After fixing the problems, your app should works as shown in the example below.
Replace:
if __name__="__main__":
with:
if __name__ == "__main__":
Example
main.py
from kivy.app import App
class WeatherApp(App):
pass
if __name__ == "__main__":
WeatherApp().run()
weather.kv
#:kivy 1.10.0
Label:
text: "hello world"
Output

Categories

Resources