Building Kivy Python executable with pyinstaller is failing
Env(virtual environment):
OS Ubuntu 22.04.4 Python 3.12.4 Kivy 2.3.0 pyinstaller 6.10.0
pyinstaller main.py results in multiple warnings with a last failure message stating....
AttributeError: module 'PyInstaller.depend.bindepend' has no attribute 'selectImports'
Originally I posted the above under pyinstaller bug reports and got 2 responses.....
One was totally unhelpful and dismissive blaming Kivy and it's hooks. The other did offer a possible fix with the following:
maltfield@host pyinstaller_hooks % diff init.py.old init.py 81c81,87 < from PyInstaller.depend import bindepend
#from PyInstaller.depend import bindepend try: # Pyinstaller >= 6 from PyInstaller.depend.bindepend import get_imports except ImportError: # Pyinstaller < 6 from PyInstaller.depend.bindepend import selectImports as get_imports 370c376,377 < plugin_deps = bindepend.selectImports(plugin_filepath)
#plugin_deps = bindepend.selectImports(plugin_filepath) plugin_deps = get_imports(plugin_filepath)
maltfield@host pyinstaller_hooks %
I modified the python_hooks script and was able to compile cleanly producing a executable but when I attempted to run the executable from a separate directory with _internal and the database (sqlite3) copied to it fails to start stating the follow:
[CRITICAL] [APPLICATION] No window is created. Terminating application run.
Can you build a basic hello world app with Kivy? If not you can try: https://kivyschool.com/pyinstaller-instructions/#step-1-have-a-working-kivy-app-to-package
Can you do a minimal runnable example with all your requirements so I can check it out?
Hi
I use pip to install modules in my virtual environment which is venv much like what pycharm does. (python3.12 -m venv venv, listed at top)
Pyinstaller is installed under that environment and enabled during attempt.
Stripped out all KivyMD so the application is simpler and now opens a main screen that shows an image / label and checks its database to ensure it exists, has data in it. As it checks the database the label's text is updated showing progress until finished.
Appreciate the help and or suggestions greatly !
(venv)virtual_dir$ pyinstaller main.py
99 INFO: PyInstaller: 6.10.0, contrib hooks: 2024.8
99 INFO: Python: 3.12.4
101 INFO: Platform: Linux-6.8.0-40-generic-x86_64-with-glibc2.35
101 INFO: Python environment: /home/weave/Python_Work/CanDoIt(kivy only)/venv
101 INFO: wrote /home/weave/Python_Work/CanDoIt(kivy only)/main.spec
103 INFO: Module search paths (PYTHONPATH):
['/usr/lib/python312.zip',
'/usr/lib/python3.12',
'/usr/lib/python3.12/lib-dynload',
'/home/weave/Python_Work/CanDoIt(kivy only)/venv/lib/python3.12/site-packages',
'/home/weave/Python_Work/CanDoIt(kivy '
'only)/venv/lib/python3.12/site-packages/setuptools/_vendor',
'/home/weave/Python_Work/CanDoIt(kivy only)']
236 INFO: checking Analysis
236 INFO: Building Analysis because Analysis-00.toc is non existent
236 INFO: Running Analysis Analysis-00.toc
236 INFO: Target bytecode optimization level: 0
236 INFO: Initializing module dependency graph...
254 INFO: Caching module graph hooks...
271 INFO: Analyzing base_library.zip ...
1375 INFO: Processing standard module hook 'hook-heapq.py' from '/home/weave/Python_Work/CanDoIt(kivy only)/venv/lib/python3.12/site-packages/PyInstaller/hooks'
1514 INFO: Processing standard module hook 'hook-encodings.py' from '/home/weave/Python_Work/CanDoIt(kivy only)/venv/lib/python3.12/site-packages/PyInstaller/hooks'
4078 INFO: Processing standard module hook 'hook-pickle.py' from '/home/weave/Python_Work/CanDoIt(kivy only)/venv/lib/python3.12/site-packages/PyInstaller/hooks'
6048 INFO: Caching module dependency graph...
6162 INFO: Looking for Python shared library...
6245 INFO: Using Python shared library: /lib/x86_64-linux-gnu/libpython3.12.so
6245 INFO: Analyzing /home/weave/Python_Work/CanDoIt(kivy only)/main.py
6268 INFO: Processing standard module hook 'hook-kivy.py' from '/home/weave/Python_Work/CanDoIt(kivy only)/venv/lib/python3.12/site-packages/PyInstaller/hooks'
6275 INFO: Kivy: v2.3.0
6275 INFO: Logger: Record log in /home/weave/.kivy/logs/kivy_24-08-18_1.txt
[INFO ] [Logger ] Record log in /home/weave/.kivy/logs/kivy_24-08-18_1.txt
[INFO ] [Kivy ] v2.3.0
6275 INFO: Kivy: Installed at "/home/weave/Python_Work/CanDoIt(kivy only)/venv/lib/python3.12/site-packages/kivy/init.py"
[INFO ] [Kivy ] Installed at "/home/weave/Python_Work/CanDoIt(kivy only)/venv/lib/python3.12/site-packages/kivy/init.py"
6275 INFO: Python: v3.12.4 (main, Jun 8 2024, 18:29:57) [GCC 11.4.0]
[INFO ] [Python ] v3.12.4 (main, Jun 8 2024, 18:29:57) [GCC 11.4.0]
6275 INFO: Python: Interpreter at "/home/weave/Python_Work/CanDoIt(kivy only)/venv/bin/python3.12"
[INFO ] [Python ] Interpreter at "/home/weave/Python_Work/CanDoIt(kivy only)/venv/bin/python3.12"
6276 INFO: Logger: Purge log fired. Processing...
[INFO ] [Logger ] Purge log fired. Processing...
6277 INFO: Logger: Purge finished!
[INFO ] [Logger ] Purge finished!
6280 INFO: Factory: 195 symbols loaded
[INFO ] [Factory ] 195 symbols loaded
6280 DEBUG: Collecting submodules for kivy.graphics
[DEBUG ] Collecting submodules for kivy.graphics
[INFO ] [Logger ] Record log in /home/weave/.kivy/logs/kivy_24-08-18_2.txt
[INFO ] [Kivy ] v2.3.0
[INFO ] [Kivy ] Installed at "/home/weave/Python_Work/CanDoIt(kivy only)/venv/lib/python3.12/site-packages/kivy/init.py"
[INFO ] [Python ] v3.12.4 (main, Jun 8 2024, 18:29:57) [GCC 11.4.0]
[INFO ] [Python ] Interpreter at "/home/weave/Python_Work/CanDoIt(kivy only)/venv/bin/python3.12"
[INFO ] [Logger ] Purge log fired. Processing...
[INFO ] [Logger ] Purge finished!
73 INFO: Kivy: v2.3.0
74 INFO: Logger: Record log in /home/weave/.kivy/logs/kivy_24-08-18_3.txt
[INFO ] [Logger ] Record log in /home/weave/.kivy/logs/kivy_24-08-18_3.txt
[INFO ] [Kivy ] v2.3.0
74 INFO: Kivy: Installed at "/home/weave/Python_Work/CanDoIt(kivy only)/venv/lib/python3.12/site-packages/kivy/init.py"
[INFO ] [Kivy ] Installed at "/home/weave/Python_Work/CanDoIt(kivy only)/venv/lib/python3.12/site-packages/kivy/init.py"
74 INFO: Python: v3.12.4 (main, Jun 8 2024, 18:29:57) [GCC 11.4.0]
[INFO ] [Python ] v3.12.4 (main, Jun 8 2024, 18:29:57) [GCC 11.4.0]
74 INFO: Python: Interpreter at "/home/weave/Python_Work/CanDoIt(kivy only)/venv/bin/python3.12"
[INFO ] [Python ] Interpreter at "/home/weave/Python_Work/CanDoIt(kivy only)/venv/bin/python3.12"
74 INFO: Logger: Purge log fired. Processing...
[INFO ] [Logger ] Purge log fired. Processing...
76 INFO: Logger: Purge finished!
[INFO ] [Logger ] Purge finished!
119 INFO: Image: Providers: img_tex, img_dds, img_sdl2 (img_pil, img_ffpyplayer ignored)
[INFO ] [Image ] Providers: img_tex, img_dds, img_sdl2 (img_pil, img_ffpyplayer ignored)
126 DEBUG: collect_submodules - scanning (sub)package kivy.graphics in location(s): ['/home/weave/Python_Work/CanDoIt(kivy only)/venv/lib/python3.12/site-packages/kivy/graphics']
[DEBUG ] [collect_submodules - scanning (sub)package kivy.graphics in location(s)] ['/home/weave/Python_Work/CanDoIt(kivy only)/venv/lib/python3.12/site-packages/kivy/graphics']
127 DEBUG: collect_submodules - scanning (sub)package kivy.graphics.cgl_backend
[DEBUG ] collect_submodules - scanning (sub)package kivy.graphics.cgl_backend
127 DEBUG: collect_submodules - scanning (sub)package kivy.graphics.cgl_backend in location(s): ['/home/weave/Python_Work/CanDoIt(kivy only)/venv/lib/python3.12/site-packages/kivy/graphics/cgl_backend']
[DEBUG ] [collect_submodules - scanning (sub)package kivy.graphics.cgl_backend in location(s)] ['/home/weave/Python_Work/CanDoIt(kivy only)/venv/lib/python3.12/site-packages/kivy/graphics/cgl_backend']
6665 DEBUG: collect_submodules - found submodules: ['kivy.graphics', 'kivy.graphics.boxshadow', 'kivy.graphics.buffer', 'kivy.graphics.cgl', 'kivy.graphics.cgl_backend', 'kivy.graphics.cgl_backend.cgl_debug', 'kivy.graphics.cgl_backend.cgl_gl', 'kivy.graphics.cgl_backend.cgl_glew', 'kivy.graphics.cgl_backend.cgl_mock', 'kivy.graphics.cgl_backend.cgl_sdl2', 'kivy.graphics.compiler', 'kivy.graphics.context', 'kivy.graphics.context_instructions', 'kivy.graphics.fbo', 'kivy.graphics.gl_instructions', 'kivy.graphics.instructions', 'kivy.graphics.opengl', 'kivy.graphics.opengl_utils', 'kivy.graphics.scissor_instructions', 'kivy.graphics.shader', 'kivy.graphics.stencil_instructions', 'kivy.graphics.svg', 'kivy.graphics.tesselator', 'kivy.graphics.texture', 'kivy.graphics.transformation', 'kivy.graphics.vbo', 'kivy.graphics.vertex', 'kivy.graphics.vertex_instructions']
[DEBUG ] [collect_submodules - found submodules] ['kivy.graphics', 'kivy.graphics.boxshadow', 'kivy.graphics.buffer', 'kivy.graphics.cgl', 'kivy.graphics.cgl_backend', 'kivy.graphics.cgl_backend.cgl_debug', 'kivy.graphics.cgl_backend.cgl_gl', 'kivy.graphics.cgl_backend.cgl_glew', 'kivy.graphics.cgl_backend.cgl_mock', 'kivy.graphics.cgl_backend.cgl_sdl2', 'kivy.graphics.compiler', 'kivy.graphics.context', 'kivy.graphics.context_instructions', 'kivy.graphics.fbo', 'kivy.graphics.gl_instructions', 'kivy.graphics.instructions', 'kivy.graphics.opengl', 'kivy.graphics.opengl_utils', 'kivy.graphics.scissor_instructions', 'kivy.graphics.shader', 'kivy.graphics.stencil_instructions', 'kivy.graphics.svg', 'kivy.graphics.tesselator', 'kivy.graphics.texture', 'kivy.graphics.transformation', 'kivy.graphics.vbo', 'kivy.graphics.vertex', 'kivy.graphics.vertex_instructions']
6693 WARNING: stderr: Traceback (most recent call last):
Traceback (most recent call last):
6693 WARNING: stderr: File "/home/weave/Python_Work/CanDoIt(kivy only)/venv/bin/pyinstaller", line 10, in
Code:
main.py:
from kivy.app import App
from kivy.clock import Clock
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image
from kivy.uix.label import Label
from kivy.uix.screenmanager import ScreenManager
from data_routines import DataRtns
class StatLabel(Label):
def on_text(self, instance, value):
self.parent.parent.parent.parent.status = value
class Interface(ScreenManager):
status = "Data Routines"
err_flg = False
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.clock = Clock.schedule_once(self.process_data, 5)
def process_data(self, dt):
if self.status == "Data Routines":
DataRtns.validate_database(self)
elif self.status == "Validated Database":
DataRtns.check_tables(self)
elif self.status == "Checked Tables":
DataRtns.check_defaults(self)
elif self.status == "Checked Defaults":
self.ids.status_indicator.text = "Finished"
if self.status != "Finished":
self.clock.cancel()
if self.err_flg:
print(self.ids.status_indicator.text)
App.get_running_app().stop()
else:
self.clock = Clock.schedule_once(self.process_data, 5)
class CandoitApp(App):
def build(self):
self.title = "Can Do IT Application"
self.icon = "cando.png"
if __name__ == "__main__":
CandoitApp().run()
data_routines.py:
from sqlite3 import connect
class DataRtns:
db = None
cursor = None
@staticmethod
def validate_database(interface):
# Create a Connection to Data, create Database if it doesn't exist
try:
DataRtns.db = connect("shipping.db")
DataRtns.cursor = DataRtns.db.cursor()
except Exception as err:
interface.err_flg = True
interface.ids.status_indicator.text = "Connection Failed: " + str(err)
if interface.err_flg == False:
interface.ids.status_indicator.text = "Validated Database"
@staticmethod
def check_tables(interface):
# Validate Tables, create if they don't exist
files = ["addresses", "schedule", "addr_types", "prefixes", "suffixes", "service_types"]
for file in files:
if file == "addresses":
try:
DataRtns.cursor.execute("CREATE TABLE IF NOT EXISTS addresses(id INTEGER PRIMARY KEY, "
"street_no INTEGER NOT NULL, street_name TEXT NOT NULL, "
"street_suffix TEXT NOT NULL, street_prefix TEXT, "
"unit_suite TEXT, city TEXT NOT NULL, province TEXT NOT NULL, "
"postal TEXT NOT NULL, landline TEXT, cell TEXT, "
"address_type TEXT NOT NULL, map TEXT, photo TEXT, "
"directions TEXT, location_notes TEXT, "
"cancellations INTEGER DEFAULT 0, failures INTEGER DEFAULT 0, "
"completed INTEGER DEFAULT 0, status TEXT, "
"status_description TEXT, time_stamp TEXT)")
except Exception as err:
DataRtns.db.close()
interface.err_flg = True
interface.ids.status_indicator.text = "Problem with addresses: " + str(err)
break
elif file == "schedule":
try:
DataRtns.cursor.execute("CREATE TABLE IF NOT EXISTS schedule(rowid INTEGER PRIMARY KEY, "
"addrid INTEGER NOT NULL, address TEXT NOT NULL, "
"city TEXT NOT NULL, type TEXT NOT NULL, "
"notes TEXT, status TEXT, time_stamp TEXT)")
except Exception as err:
DataRtns.db.close()
interface.err_flg = True
interface.ids.status_indicator.text = "Problem with schedule: " + str(err)
break
elif file == "addr_types":
try:
DataRtns.cursor.execute("CREATE TABLE IF NOT EXISTS addr_types(id INTEGER PRIMARY KEY, "
"type TEXT NOT NULL, multi_unit INTEGER DEFAULT 0)")
except Exception as err:
DataRtns.db.close()
interface.err_flg = True
interface.ids.status_indicator.text = "Problem with addr_types: " + str(err)
break
elif file == "prefixes":
try:
DataRtns.cursor.execute("CREATE TABLE IF NOT EXISTS prefixes(id INTEGER PRIMARY KEY, "
"street_direction TEXT NOT NULL, abbreviation TEXT NOT NULL)")
except Exception as err:
DataRtns.db.close()
interface.err_flg = True
interface.ids.status_indicator.text = "Problem with prefixes: " + str(err)
break
elif file == "suffixes":
try:
DataRtns.cursor.execute("CREATE TABLE IF NOT EXISTS suffixes(id INTEGER PRIMARY KEY, "
"street_type TEXT NOT NULL, abbreviation TEXT NOT NULL)")
except Exception as err:
DataRtns.db.close()
interface.err_flg = True
interface.ids.status_indicator.text = "Problem with suffixes: " + str(err)
break
elif file == "service_types":
try:
DataRtns.cursor.execute("CREATE TABLE IF NOT EXISTS service_types(id INTEGER PRIMARY KEY, "
"type TEXT NOT NULL)")
except Exception as err:
DataRtns.db.close()
interface.err_flg = True
interface.ids.status_indicator.text = "Problem with service_types: " + str(err)
break
if interface.err_flg == False:
interface.ids.status_indicator.text = "Checked Tables"
@staticmethod
def check_defaults(interface):
# Validate Maintenance Files, should contain default values used in the application
result = []
chk_result = []
files = ["addr_types", "prefixes", "suffixes", "service_types"]
for file in files:
if interface.err_flg:
break
if file == "addr_types":
# Address Type Defaults
values = [("Apartment Building", 1),
("Assisted Living Building", 1),
("Basement Apartment", 0),
("Business (detached)", 0),
("Condominium", 1),
("Flat", 0),
("House (detached)", 0),
("House (linked)", 0),
("Loft", 0),
("Maisonette", 1),
("Office Building", 1),
("Retirement Home", 1),
("Row House", 1),
("Seniors Residence", 1),
("Store Front", 0),
("Plaza", 1),
("Mall", 1),
("Townhouse", 1),
("Townhouse (no unit)", 0),
("Trailer Park", 0)]
# Access addr_types
try:
sql = f"SELECT * from {file}"
DataRtns.cursor.execute(sql)
result = DataRtns.cursor.fetchall()
except Exception as err:
DataRtns.db.close()
interface.err_flg = True
interface.ids.status_indicator.text = "Problem accessing addr_types: " + str(err)
break
# Check Records
if len(result) > 0:
for value_items in values:
try:
sql = f"SELECT * from {file} where type = '{value_items[0]}'"
DataRtns.cursor.execute(sql)
chk_result = DataRtns.cursor.fetchall()
except Exception as err:
DataRtns.db.close()
interface.err_flg = True
interface.ids.status_indicator.text = f"Problem accessing {file}: " + str(err)
break
if len(chk_result) == 0:
desc = value_items[0]
munit = value_items[1]
try:
sql = f"INSERT INTO {file} (type, multi_unit) VALUES (?, ?)"
vals = (f"{desc}", f"{munit}")
DataRtns.cursor.execute(sql, vals)
DataRtns.db.commit()
except Exception as err:
DataRtns.db.close()
interface.err_flg = True
interface.ids.status_indicator.text = f"Problem update {file}: " + str(err)
break
else:
# Add Records
for value_items in values:
desc = value_items[0]
munit = value_items[1]
try:
sql = f"INSERT INTO {file} (type, multi_unit) VALUES (?, ?)"
vals = (f"{desc}", f"{munit}")
DataRtns.cursor.execute(sql, vals)
DataRtns.db.commit()
except Exception as err:
DataRtns.db.close()
interface.err_flg = True
interface.ids.status_indicator.text = f"Problem updating {file}: " + str(err)
break
elif file == "prefixes":
# Street Direction Defaults
values = [("East", "E"),
("North", "N"),
("Northeast", "NE"),
("Northwest", "NW"),
("South", "S"),
("Southeast", "SE"),
("Southwest", "SW"),
("West", "W")]
# Access prefixes
try:
sql = f"SELECT * from {file}"
DataRtns.cursor.execute(sql)
result = DataRtns.cursor.fetchall()
except Exception as err:
DataRtns.db.close()
interface.err_flg = True
interface.ids.status_indicator.text = "Problem accessing prefixes: " + str(err)
break
# Check Records
if len(result) > 0:
for value_items in values:
try:
sql = f"SELECT * from {file} where street_direction = '{value_items[0]}'"
DataRtns.cursor.execute(sql)
chk_result = DataRtns.cursor.fetchall()
except Exception as err:
DataRtns.db.close()
interface.err_flg = True
interface.ids.status_indicator.text = f"Problem accessing {file}: " + str(err)
break
if len(chk_result) == 0:
direction = value_items[0]
short_desc = value_items[1]
try:
sql = f"INSERT INTO {file} (street_direction, abbreviation) VALUES (?, ?)"
vals = (f"{direction}", f"{short_desc}")
DataRtns.cursor.execute(sql, vals)
DataRtns.db.commit()
except Exception as err:
DataRtns.db.close()
interface.err_flg = True
interface.ids.status_indicator.text = f"Problem updating {file}: " + str(err)
break
else:
# Add Records
for value_items in values:
direction = value_items[0]
short_desc = value_items[1]
try:
sql = f"INSERT INTO {file} (street_direction, abbreviation) VALUES (?, ?)"
vals = (f"{direction}", f"{short_desc}")
DataRtns.cursor.execute(sql, vals)
DataRtns.db.commit()
except Exception as err:
DataRtns.db.close()
interface.err_flg = True
interface.ids.status_indicator.text = f"Problem updating {file}: " + str(err)
break
elif file == "suffixes":
# Street Type Defaults
values = [("Abbey", "Abbey"),
("Acres", "Acres"),
("Alley", "Alley"),
("Avenue", "Ave"),
("Bay", "Bay"),
("Beach", "Beach"),
("Boulevard", "Blvd"),
("Bye-pass", "Bypass"),
("Campus", "Campus"),
("Centre", "Ctr"),
("Circle", "Cir"),
("Concession", "Conc"),
("Corners", "Crnrs"),
("Court", "Crt"),
("Cove", "Cove"),
("Crescent", "Cres"),
("Crossing", "Cross"),
("Downs", "Downs"),
("Drive", "Dr"),
("Esplanade", "Espl"),
("Expressway", "Expy"),
("Extension", "Exten"),
("Freeway", "Fwy"),
("Glen", "Glen"),
("Grove", "Grove"),
("Harbour", "Harbr"),
("Heights", "Hts"),
("Highway", "Hwy"),
("Hill", "Hill"),
("Key", "Key"),
("Landing", "Landing"),
("Lane", "Lane"),
("Line", "Line"),
("Mall", "Mall"),
("Manor", "Manor"),
("Meadows", "Meadows"),
("Mews", "Mews"),
("Mountain", "Mtn"),
("Orchard", "Orch"),
("Park", "Pk"),
("Parkway", "Pky"),
("Place", "Pl"),
("Plaza", "Plaza"),
("Promenade", "Prom"),
("Ridge", "Ridge"),
("Road", "Rd"),
("Route", "Rte"),
("Square", "Sq"),
("Street", "St"),
("Terrace", "Terr"),
("Towers", "Towers"),
("Townline", "Tline"),
("Trail", "Trail"),
("View", "View"),
("Village", "Vilge"),
("Way", "Way")]
# Access Street Types
try:
sql = f"SELECT * from {file}"
DataRtns.cursor.execute(sql)
result = DataRtns.cursor.fetchall()
except Exception as err:
DataRtns.db.close()
interface.err_flg = True
interface.ids.status_indicator.text = f"Problem accessing suffixes: " + str(err)
break
# Check Records
if len(result) > 0:
for value_items in values:
try:
sql = f"SELECT * from {file} where street_type = '{value_items[0]}'"
DataRtns.cursor.execute(sql)
chk_result = DataRtns.cursor.fetchall()
except Exception as err:
DataRtns.db.close()
interface.err_flg = True
interface.ids.status_indicator.text = f"Problem accessing {file}: " + str(err)
break
if len(chk_result) == 0:
strt_type = value_items[0]
short_desc = value_items[1]
try:
sql = f"INSERT INTO {file} (street_type, abbreviation) VALUES (?, ?)"
vals = (f"{strt_type}", f"{short_desc}")
DataRtns.cursor.execute(sql, vals)
DataRtns.db.commit()
except Exception as err:
DataRtns.db.close()
interface.err_flg = True
interface.ids.status_indicator = f"Problem updateing {file}: " + str(err)
break
else:
# Add Records
for value_items in values:
strt_type = value_items[0]
short_desc = value_items[1]
try:
sql = f"INSERT INTO {file} (street_type, abbreviation) VALUES (?, ?)"
vals = (f"{strt_type}", f"{short_desc}")
DataRtns.cursor.execute(sql, vals)
DataRtns.db.commit()
except Exception as err:
DataRtns.db.close()
interface.err_flg = True
interface.ids.status_indicator.text = f"Problem updating {file}: " + str(err)
break
elif file == "service_types":
# Service Type Defaults
values = ["Delivery",
"Desk Work",
"Dog Walking",
"Gardening",
"Lawn Mow",
"Leaf Raking",
"Other",
"Pet Sitting",
"Put Garbage Out",
"Snow Shoveling",
"Trash Removal"]
# Access service_types
try:
sql = f"SELECT * from {file}"
DataRtns.cursor.execute(sql)
result = DataRtns.cursor.fetchall()
except Exception as err:
DataRtns.db.close()
interface.err_flg = True
interface.ids.status_indicator.text = f"Problem accessing service_types: " + str(err)
break
# Check Records
if len(result) > 0:
for value_items in values:
try:
sql = f"SELECT * from {file} where type = '{value_items[0]}'"
DataRtns.cursor.execute(sql)
chk_result = DataRtns.cursor.fetchall()
except Exception as err:
DataRtns.db.close()
interface.err_flg = True
interface.ids.status_indicator.text = f"Problem accessing {file}: " + str(err)
break
if len(chk_result) == 0:
service = value_items[0]
try:
sql = f"INSERT INTO {file} (type) VALUES (?)"
vals = f"{service}"
DataRtns.cursor.execute(sql, vals)
DataRtns.db.commit()
except Exception as err:
DataRtns.db.close()
interface.err_flg = True
interface.ids.status_indicator.text = f"Problem updating {file}: " + str(err)
break
else:
# Add Records
for value_items in values:
service = value_items[0]
try:
sql = f"INSERT INTO {file} (type) VALUES (?)"
vals = f"{service}"
DataRtns.cursor.execute(sql, vals)
DataRtns.db.commit()
except Exception as err:
DataRtns.db.close()
interface.err_flg = True
interface.ids.status_indicator.text = f"Problem updating {file}: " + str(err)
break
if interface.err_flg == False:
DataRtns.cursor.close()
DataRtns.db.close()
interface.ids.status_indicator.text = "Checked Defaults"
candoit.kv:
Interface:
Screen:
name: "Splash_Screen"
canvas.before:
Color:
rgba: .6, .8, 1, 1
Rectangle:
pos: self.pos
size: self.size
AnchorLayout:
anchor_x: "center"
anchor_y: "center"
BoxLayout:
orientation: "vertical"
size_hint: None, None
width: dp(300)
height: dp(300)
Image:
source: "cando.png"
size_hint: 1, 0.9
StatLabel:
id: status_indicator
text: root.status
font_size: "32sp"
color: [0, 0, 0, 1]
size_hint: 1, 0.1
I was able to build it w/o the logo though, u need to remember to add the logo to the datas as well. the kivyschool pyinstaller page talks about it on step 4b
3 things:
thing1: u need to add ur other py files to datas:
datas=[("candoit.kv","."),("data_routines.py",".")],
thing2: add the MEIPASS folder as per cheaterman's solution here:
# https://discord.com/channels/423249981340778496/741935529838379028/1148697678004363284
import sys, os
if not sys.stderr:
os.environ['KIVY_NO_CONSOLELOG'] = '1'
from kivy.resources import resource_add_path
if getattr(sys, 'frozen', False):
resource_add_path(sys._MEIPASS)
third thing: put the kivy app run code in a try except block with a timer so that when it errors out you can observe the console log. This is because when the app exits, there is no more python code running, and windows automatically closes the window.
main.py
# https://github.com/kivy/kivy/issues/8802
from kivy.app import App
from kivy.clock import Clock
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image
from kivy.uix.label import Label
from kivy.uix.screenmanager import ScreenManager
from data_routines import DataRtns
# https://discord.com/channels/423249981340778496/741935529838379028/1148697678004363284
import sys, os
if not sys.stderr:
os.environ['KIVY_NO_CONSOLELOG'] = '1'
from kivy.resources import resource_add_path
if getattr(sys, 'frozen', False):
resource_add_path(sys._MEIPASS)
class StatLabel(Label):
def on_text(self, instance, value):
self.parent.parent.parent.parent.status = value
class Interface(ScreenManager):
status = "Data Routines"
err_flg = False
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.clock = Clock.schedule_once(self.process_data, 5)
def process_data(self, dt):
if self.status == "Data Routines":
DataRtns.validate_database(self)
elif self.status == "Validated Database":
DataRtns.check_tables(self)
elif self.status == "Checked Tables":
DataRtns.check_defaults(self)
elif self.status == "Checked Defaults":
self.ids.status_indicator.text = "Finished"
if self.status != "Finished":
self.clock.cancel()
if self.err_flg:
print(self.ids.status_indicator.text)
App.get_running_app().stop()
else:
self.clock = Clock.schedule_once(self.process_data, 5)
class CandoitApp(App):
def build(self):
self.title = "Can Do IT Application"
# self.icon = "cando.png"
if __name__ == "__main__":
try:
CandoitApp().run()
except Exception as e:
import traceback
print("full exception", "".join(traceback.format_exception(*sys.exc_info())))
import time
time.sleep(10)
candoit.spec
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['main6.py'],
pathex=[],
binaries=[],
datas=[("candoit.kv","."),("data_routines.py",".")],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='candoit',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
to use this specfile, run python -m PyInstaller candoit.spec --clean
Hi AccelQuasarDragon
Modified both the main.spec, main.py and ran the pyinstaller twice, once as I would do normally from within my development env and as you'd shown above but I'm sorry to report I got the same error.... still complaning about select imports.
Do I need to add Sqlite to datas and if so what would be that entry ?
Sorry about the image.....
This worked for me ...
I've been asking all over the place for some help and the one (helpful reply) from Rok Mandeljc of PyInstallers Github mentioned a previous posting had a similar issue. kivy#8653. This did allow the executable to get created but it still failed when I ran it. With your changes and those below I'm now able to run the executable.
I needed to modify the init.py under kivy. (site-packages/kivy/tools/packaging/pyinstaller_hooks)
#from PyInstaller.depend import bidepend
try:
from PyInstaller.depend.bindepend import get_imports
except ImportError:
from PyInstaller.depend.bindepend import selectImports(plugin_filepath)
#plugin_deps = bindepend.selectImports(plugin_filepath)
plugin_deps = get_imports(plugin_filepath)
Appreciate all your help provided. Would be interested to know if the above can be applied to future releases of kivy or is this a patch only for the meantime.
Don
One step forward 2 steps back as they say ...
Ran the above against my complete application which includes KivyMD as well and it's failing with a different error.
pyinstaller main.spec
112 INFO: PyInstaller: 6.10.0, contrib hooks: 2024.8
112 INFO: Python: 3.12.5
114 INFO: Platform: Linux-6.8.0-40-generic-x86_64-with-glibc2.35
114 INFO: Python environment: /home/weave/Python_Work/CanDoIt/venv
116 DEPRECATION: Foreign Python environment's site-packages paths added to --paths/pathex:
['./venv/lib64/python3.12/site-packages']
This is ALWAYS the wrong thing to do. If your environment's site-packages is not in PyInstaller's module search path then you are running PyInstaller from a different environment to the one your packages are in. Run print(sys.prefix) without PyInstaller to get the environment you should be using then install and run PyInstaller from that environment instead of this one. This warning will become an error in PyInstaller 7.0.
116 INFO: Module search paths (PYTHONPATH):
['/usr/lib/python312.zip',
'/usr/lib/python3.12',
'/usr/lib/python3.12/lib-dynload',
'/home/weave/Python_Work/CanDoIt/venv/lib/python3.12/site-packages',
'/home/weave/Python_Work/CanDoIt/venv/lib/python3.12/site-packages/setuptools/_vendor',
'/home/weave/Python_Work/CanDoIt',
'/home/weave/Python_Work/CanDoIt/venv/lib64/python3.12/site-packages']
22 INFO: Kivy: v2.3.0
23 INFO: Logger: Record log in /home/weave/.kivy/logs/kivy_24-08-20_5.txt
[INFO ] [Logger ] Record log in /home/weave/.kivy/logs/kivy_24-08-20_5.txt
[INFO ] [Kivy ] v2.3.0
23 INFO: Kivy: Installed at "/home/weave/Python_Work/CanDoIt/venv/lib/python3.12/site-packages/kivy/init.py"
[INFO ] [Kivy ] Installed at "/home/weave/Python_Work/CanDoIt/venv/lib/python3.12/site-packages/kivy/init.py"
23 INFO: Python: v3.12.5 (main, Aug 17 2024, 16:46:05) [GCC 11.4.0]
[INFO ] [Python ] v3.12.5 (main, Aug 17 2024, 16:46:05) [GCC 11.4.0]
23 INFO: Python: Interpreter at "/home/weave/Python_Work/CanDoIt/venv/bin/python3.12"
[INFO ] [Python ] Interpreter at "/home/weave/Python_Work/CanDoIt/venv/bin/python3.12"
23 INFO: Logger: Purge log fired. Processing...
[INFO ] [Logger ] Purge log fired. Processing...
25 INFO: Logger: Purge finished!
[INFO ] [Logger ] Purge finished!
26 INFO: KivyMD: 2.0.1.dev0, git-Unknown, 2024-08-20 (installed at "/home/weave/Python_Work/CanDoIt/venv/lib/python3.12/site-packages/kivymd/init.py")
[INFO ] [KivyMD ] 2.0.1.dev0, git-Unknown, 2024-08-20 (installed at "/home/weave/Python_Work/CanDoIt/venv/lib/python3.12/site-packages/kivymd/init.py")
27 INFO: Factory: 195 symbols loaded
[INFO ] [Factory ] 195 symbols loaded
99 INFO: Image: Providers: img_tex, img_dds, img_sdl2, img_pil (img_ffpyplayer ignored)
[INFO ] [Image ] Providers: img_tex, img_dds, img_sdl2, img_pil (img_ffpyplayer ignored)
107 INFO: Text: Provider: sdl2
[INFO ] [Text ] Provider: sdl2
250 INFO: Window: Provider: sdl2
[INFO ] [Window ] Provider: sdl2
601 INFO: GL: Using the "OpenGL" graphics system
[INFO ] [GL ] Using the "OpenGL" graphics system
602 INFO: GL: Backend used
6577 WARNING: stderr: During handling of the above exception, another exception occurred: During handling of the above exception, another exception occurred: 6577 WARNING: stderr:
6577 WARNING: stderr: Traceback (most recent call last):
Traceback (most recent call last):
6577 WARNING: stderr: File "/home/weave/Python_Work/CanDoIt/venv/bin/pyinstaller", line 8, in
Missing module __Pyinstaller_hooks_0_kivy, checked and there's nothing under my virtual environment directory.
Any idea what's going wrong now ?
Ok, that problem has been fixed in the latest version of kivy-reloader. Can you update kivy-reloader and try again?
I had the same problem, but was able to fix it by modifying the _find_gst_binaries() method in the mentioned init.py in site-packages/kivy/tools/packaging/pyinstaller_hooks. I modified:
lib_filepaths = set()
for plugin_filepath in plugin_filepaths:
plugin_deps = bindepend.selectImports(plugin_filepath)
lib_filepaths.update([path for _, path in plugin_deps])
to:
lib_filepaths = set()
for plugin_filepath in plugin_filepaths:
plugin_deps = []
if hasattr(bindepend, 'get_imports'):
plugin_deps = bindepend.get_imports(plugin_filepath)
else:
plugin_deps = bindepend.selectImports(plugin_filepath)
lib_filepaths.update([path for _, path in plugin_deps])
This works for me!!!
Wow, can confirm DaytonaJohn's edit was the fix, worked for me on Ubuntu 24.04 on Virtualbox.