mherrmann / fbs Goto Github PK
View Code? Open in Web Editor NEWCreate Python GUIs with Qt in minutes
Home Page: https://build-system.fman.io
License: GNU General Public License v3.0
Create Python GUIs with Qt in minutes
Home Page: https://build-system.fman.io
License: GNU General Public License v3.0
I am trying to freeze my project but am receiving a KeyError
for SETTINGS[app_name]
.
Traceback (most recent call last):
File "C:\Users\lspmpc\Anaconda3\lib\runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "C:\Users\lspmpc\Anaconda3\lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "C:\Users\lspmpc\Anaconda3\lib\site-packages\fbs\__main__.py", line 4, in <module>
main()
File "C:\Users\lspmpc\Anaconda3\lib\site-packages\fbs\cmdline.py", line 25, in main
args.fn(*fn_args)
File "C:\Users\lspmpc\Anaconda3\lib\site-packages\fbs\builtin_commands\__init__.py", line 73, in freeze
freeze_windows(debug=debug)
File "C:\Users\lspmpc\Anaconda3\lib\site-packages\fbs\freeze\windows.py", line 21, in freeze_windows
run_pyinstaller(pyinstaller_args + extra_pyinstaller_args, debug)
File "C:\Users\lspmpc\Anaconda3\lib\site-packages\fbs\freeze\__init__.py", line 9, in run_pyinstaller
app_name = SETTINGS['app_name']
KeyError: 'app_name'
From the src
folder I am running python -m fbs freeze
. I have tried this with a fresh project *created with python -m fbs startproject
, with the same result. I checked the src/build/settings.base.json
file, and everything seems correct.
I am on a Windows 10 machine with Python 3.6.5
Thank you
I noticed that you're using tabs to indent your code. I personally prefer spaces and use this everywhere. Even PEP8 recommends spaces over tabs.
I believe Python 3 is more picky about mixing spaces and tabs and won't accept such mixing without raising errors (not entirely sure here). Since this is an open source project, perhaps I can persuade you to follow the PEP8 recommendations and use (4) spaces instead of a tab? 😉
I suspect that the last step of the installer (which offers the ability to launch the frozen application) is using the same environment as the installer itself. In my case, this means that administrative permissions are enabled.
When my application runs, it creates files on disk. When the application recognizes very old and unused such files, it attempts to delete them. This, however, fails, as some of these files were created from an application instance which got launched from the installer and now requires admin permissions for deletion. This is on Windows.
I recently found out that you can force an application to run as "non-administrative" using runas
on Windows:
runas /trustlevel:0x20000 "SpotifyFullSetup.exe /silent"
In the Installer.nsi
file, I'm going to attempt to do this for Windows. But I don't have a solution for macOS or Linux, but I'm not sure whether the issue is being hit on those operating systems at all.
This is what the launch command of the Installer.nsi
looks like:
Function LaunchLink
ExecShell "" "$SMPROGRAMS\%{app_name}.lnk"
FunctionEnd
EDIT: I realized this doesn't belong in the fbs project, but instead in the fbs-tutorial one.
Is there a correct way to include other files/directories when building the installer/executable directory?
I'm asking because I'm loading the .ui files at runtime in my code to load the QT widgets ...etc.
class AppContext(ApplicationContext): # 1. Subclass ApplicationContext
def run(self): # 2. Implement run()
form = MainForm('forms/mainwindow.ui')
return self.app.exec_() # 3. End run() with this line
I know it has the resource/base directory, would this be the best place for my .ui files?
Great project you have going here! 🎉
Just wondering if versioning is working correctly? I saw #34 and was expecting a version number to show up in the frozen Mac app. However, it just passes the string in the Info.plist (which are just the placeholders).
Once I added a version
key to base.json
it worked correctly. Should that be in the default project template? I'm sure other users may run into this issue and I didn't see it documented in the manual.
I tried out fbs and I have the following problem.
fbs run
works well, but after fbs freeze
executing the executable file gives following error:
ModuleNotFoundError: No module named 'controller'
This error is described in https://build-system.fman.io/manual/ under Dependencies. So I tried to add:
"hidden_imports": ["controller"]
into the base.json. Afterwards i get the error:
2170 ERROR: Hidden import 'controller' not found
controller is part of my application.
The folder structure is this:
src/main/python:
- main.py
- controller:
- _init_.py
- controller.py
The main.py has this import:
from controller import EditorController
The _init_.py looks like this:
from .controller import EditorController
Is there a way to fix this problem?
Could you add AppImage support ? And/or snap package ?
It would be awesome
https://appimage.org
https://github.com/probonopd/linuxdeployqt
The official way for creating installers for Windows is WiX Toolset. Could NSIS be replaced with it?
Hi,
I wish to add git submodules to my project, and have my fbs application be able to import such submodules as import xxx
(in the case where the module in question is named xxx
). One could perhaps see this as a way of vendoring other packages into my fbs application.
This can easily be achieved when not using fbs/pyinstaller in a number of ways. The easiest one is to append the path containing the package/module into sys.path
.
But this doesn't work when freezing. I am writing here to see if @mherrmann has any suggestions...
My file structure:
src/main/python
├───myapp
│ __init__.py
│
└───submodules
└───xxx (this is the git repo)
├───.git
├───docs
├───tests
└───xxx (python package which I wish to import)
__init__.py
So, what I wish to achieve is to import xxx
from myapp
(which I am fbs-freezing).
Any ideas?
According to the site, projects can freely use fbs providing the project in question is licensed using GNU general public license. Just so I don't disobey the terms of the license; does this mean only the project using fbs, or any other projects that it would integrate with?
I was planning on using Unlicense which is a permissive license very similar to WTFGPL.
Followed tutorial to the point.
Output:
(venv) C:\Users\myuser\code\testapp>python -m fbs installer
Processing config: C:\Program Files (x86)\NSIS\nsisconf.nsh
Processing script file: "Installer.nsi" (ACP)
File: "..\TestApp\*" -> no files found.
Usage: File [/nonfatal] [/a] ([/r] [/x filespec [...]] filespec [...] |
/oname=outfile one_file_only)
Error in script "Installer.nsi" on line 70 -- aborting creation process
Traceback (most recent call last):
File "c:\users\myuser\appdata\local\programs\python\python36\Lib\runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "c:\users\myuser\appdata\local\programs\python\python36\Lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "C:\Users\myuser\code\testapp\venv\lib\site-packages\fbs\__main__.py", line 4, in <module>
main()
File "C:\Users\myuser\code\testapp\venv\lib\site-packages\fbs\cmdline.py", line 25, in main
args.fn(*fn_args)
File "C:\Users\myuser\code\testapp\venv\lib\site-packages\fbs\builtin_commands\__init__.py", line 94, in installer
create_installer_windows()
File "C:\Users\myuser\code\testapp\venv\lib\site-packages\fbs\installer\windows.py", line 19, in create_installer_windows
run(['makensis', 'Installer.nsi'], cwd=path('target/NSIS'), check=True)
File "c:\users\myuser\appdata\local\programs\python\python36\Lib\subprocess.py", line 418, in run
output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command '['makensis', 'Installer.nsi']' returned non-zero exit status 1.
Installer.nsi:
!include MUI2.nsh
!include FileFunc.nsh
;--------------------------------
;Perform Machine-level install, if possible
!define MULTIUSER_EXECUTIONLEVEL Highest
;Add support for command-line args that let uninstaller know whether to
;uninstall machine- or user installation:
!define MULTIUSER_INSTALLMODE_COMMANDLINE
!include MultiUser.nsh
!include LogicLib.nsh
Function .onInit
!insertmacro MULTIUSER_INIT
;Do not use InstallDir at all so we can detect empty $InstDir!
${If} $InstDir == "" ; /D not used
${If} $MultiUser.InstallMode == "AllUsers"
StrCpy $InstDir "$PROGRAMFILES\TestApp"
${Else}
StrCpy $InstDir "$LOCALAPPDATA\TestApp"
${EndIf}
${EndIf}
FunctionEnd
Function un.onInit
!insertmacro MULTIUSER_UNINIT
FunctionEnd
;--------------------------------
;General
Name "TestApp"
OutFile "..\TestAppSetup.exe"
;--------------------------------
;Interface Settings
!define MUI_ABORTWARNING
;--------------------------------
;Pages
!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of TestApp.$\r$\n$\r$\n$\r$\nClick Next to continue."
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!define MUI_FINISHPAGE_NOAUTOCLOSE
!define MUI_FINISHPAGE_RUN
!define MUI_FINISHPAGE_RUN_CHECKED
!define MUI_FINISHPAGE_RUN_TEXT "Run TestApp"
!define MUI_FINISHPAGE_RUN_FUNCTION "LaunchLink"
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
;--------------------------------
;Languages
!insertmacro MUI_LANGUAGE "English"
;--------------------------------
;Installer Sections
!define UNINST_KEY \
"Software\Microsoft\Windows\CurrentVersion\Uninstall\TestApp"
Section
SetOutPath "$InstDir"
File /r "..\TestApp\*"
WriteRegStr SHCTX "Software\TestApp" "" $InstDir
WriteUninstaller "$InstDir\uninstall.exe"
CreateShortCut "$SMPROGRAMS\TestApp.lnk" "$InstDir\TestApp.exe"
WriteRegStr SHCTX "${UNINST_KEY}" "DisplayName" "TestApp"
WriteRegStr SHCTX "${UNINST_KEY}" "UninstallString" \
"$\"$InstDir\uninstall.exe$\" /$MultiUser.InstallMode"
WriteRegStr SHCTX "${UNINST_KEY}" "QuietUninstallString" \
"$\"$InstDir\uninstall.exe$\" /$MultiUser.InstallMode /S"
WriteRegStr SHCTX "${UNINST_KEY}" "Publisher" "Simon Hellbe"
${GetSize} "$InstDir" "/S=0K" $0 $1 $2
IntFmt $0 "0x%08X" $0
WriteRegDWORD SHCTX "${UNINST_KEY}" "EstimatedSize" "$0"
SectionEnd
;--------------------------------
;Uninstaller Section
Section "Uninstall"
RMDir /r "$InstDir"
Delete "$SMPROGRAMS\TestApp.lnk"
DeleteRegKey /ifempty SHCTX "Software\TestApp"
DeleteRegKey SHCTX "${UNINST_KEY}"
SectionEnd
Function LaunchLink
!addplugindir "."
ShellExecAsUser::ShellExecAsUser "open" "$SMPROGRAMS\TestApp.lnk"
FunctionEnd
I'm new here and looked at https://github.com/mherrmann/fbs-tutorial
Spontaneously I thought: Why isn't there also a finished installer that sets up the fbs virtualenv for "easier" start the tutorial ?
Hi!
I'm on Windows 7 using Python 3.5.2. When I follow the tutorial's instructions to create the fbs project structure and rerun my app, I get
Traceback (most recent call last):
File "main.py", line 31, in <module>
File "C:\Users\test\testumgebung\venv\lib\site-packages\fbs_runtime\application_context.py", line 38, in __init__
self._resource_locator = self._create_resource_locator()
File "C:\Users\test\testumgebung\venv\lib\site-packages\fbs_runtime\application_context.py", line 58, in _create_resource_locator
return _DevelopmentResourceLocator(self.__class__)
File "C:\Users\test\testumgebung\venv\lib\site-packages\fbs_runtime\application_context.py", line 115, in __init__
project_dir = self._get_project_base_dir(appctxt_cls)
File "C:\Users\test\testumgebung\venv\lib\site-packages\fbs_runtime\application_context.py", line 127, in _get_project_base_dir
parent_names = [p.parents[2].name, p.parents[1].name, p.parent.name]
File "C:\Users\test\AppData\Local\Programs\Python\Python35-32\lib\pathlib.py", line 594, in __getitem__
raise IndexError(idx)
IndexError: 2
my main.py
:
#! /usr/bin/env python
# encoding: utf-8
import logging
import sys
from fbs_runtime.application_context import ApplicationContext
import pruefung
class AppContext(ApplicationContext):
def run(self):
pr = pruefung.PruefungApp()
return self.app.exec_()
if __name__ == '__main__':
appctxt = AppContext()
exit_code = appctxt.run()
sys.exit(exit_code)
pip freeze
:
altgraph==0.16.1
certifi==2018.10.15
chardet==3.0.4
fbs==0.3.6
future==0.17.1
idna==2.7
influxdb==5.2.0
iso8601==0.1.12
macholib==1.11
numpy==1.15.4
pandas==0.23.4
pefile==2018.8.8
PyInstaller==3.3.1
pypiwin32==223
PyQt5==5.9.2
pyserial==3.4
python-dateutil==2.7.5
pytz==2018.7
pywin32==224
PyYAML==3.13
requests==2.20.0
sip==4.19.8
six==1.11.0
urllib3==1.24.1
xlrd==1.1.0
Did you encounter this issue before? The error persists when I run python -m fbs startproject
. When I run python -m fbs run
I get an empty window.
My freeze fail on Windows 10 since the api-ms-win-crt-multibyte-l1-1-0.dll
file is not found:
(pyqt5_py35) C:\Users\iruser\code\repos\fbs-tutorial>python -m fbs freeze
Could not remove file: [WinError 2] The system cannot find the file specified: 'C:\\Users\\iruser\\code\\repos\\fbs-tutorial\\target\\Tutorial\\python3.dll'
Traceback (most recent call last):
File "C:\Users\iruser\AppData\Local\conda\conda\envs\pyqt5_py35\lib\runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "C:\Users\iruser\AppData\Local\conda\conda\envs\pyqt5_py35\lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "C:\Users\iruser\AppData\Local\conda\conda\envs\pyqt5_py35\lib\site-packages\fbs\__main__.py", line 4, in <module>
main()
File "C:\Users\iruser\AppData\Local\conda\conda\envs\pyqt5_py35\lib\site-packages\fbs\cmdline.py", line 17, in main
args.cmd()
File "C:\Users\iruser\AppData\Local\conda\conda\envs\pyqt5_py35\lib\site-packages\fbs\builtin_commands.py", line 35, in freeze
freeze_windows()
File "C:\Users\iruser\AppData\Local\conda\conda\envs\pyqt5_py35\lib\site-packages\fbs\freeze\windows.py", line 29, in freeze_windows
_add_missing_dlls()
File "C:\Users\iruser\AppData\Local\conda\conda\envs\pyqt5_py35\lib\site-packages\fbs\freeze\windows.py", line 37, in _add_missing_dlls
copy(join(r'c:\Windows\System32', dll), path('${freeze_dir}'))
File "C:\Users\iruser\AppData\Local\conda\conda\envs\pyqt5_py35\lib\shutil.py", line 241, in copy
copyfile(src, dst, follow_symlinks=follow_symlinks)
File "C:\Users\iruser\AppData\Local\conda\conda\envs\pyqt5_py35\lib\shutil.py", line 120, in copyfile
with open(src, 'rb') as fsrc:
FileNotFoundError: [Errno 2] No such file or directory: 'c:\\Windows\\System32\\api-ms-win-crt-multibyte-l1-1-0.dll'
I can see that the file indeed exists within the target\Tutorial
folder.
fbs currently lets you create .deb
, .rpm
and .pkg.tar.xz
packages for Ubuntu, Fedora and Arch Linux, respectively. People also often ask about support for creating AppImages.
My goal is for fbs to follow the same strategy as Linus Torvalds' Subsurface: Offer native packages for the main Linux distributions, and AppImages for users who prefer them or are on less common distributions.
The goal of this issue is thus to add support for AppImages to fbs. I am creating it not because this will likely be implemented soon (there are other, more important, tasks right now, such as code signing and automatic updates on Windows and Mac). But to document the associated considerations, and that AppImages have not been overlooked.
For previous discussions of this topic, please see #44 and #47. Especially in the latter, @probonopd did a great job of outlining the advantages of AppImages.
After building my App.exe on Windows using Python 3.6.5, I get this when I run it:
Traceback (most recent call last):
...
import ctypes, ctypes.wintypes
ModuleNotFoundError: No module named 'ctypes.wintypes'
[20024] Failed to execute script main
Have you seen anything like this?
I'm just throwing this out there... it could be PyInstaller's fault.
The AppImage format is quite popular for Python/Qt applications, because it neatly packages everything inside one single file, including Python, Qt, etc. and does not touch things in the base system.
Supporting AppImage would have, among others, these advantages for end users:
appimaged
--appimage-extract
parameterHere is an overview of projects that are already distributing upstream-provided, official AppImages.
Here is an example of a rather complex Python/Qt application distributed as an AppImage:
https://ultimaker.com/en/products/ultimaker-cura-software
If you have questions, AppImage developers are on #AppImage on irc.freenode.net.
I know QT is easy and up and coming, but the license is too restrictive for a private company to start using it professionally as a tool. I just finished a QT-based IoT OS and navigating the licensing is difficult.
I LOVE the passion you out into your FBS installers, if you're interesting in developing a second process to generate non-qt installers I'd be happy to help 👍
We could keep the exact same API
The "Recursive" keyword is not supported in Python2 and so setup.py breaks.
The Licensing heading of README.md states that:
This project is licensed under the GPL. In simple terms, this means you can use it for free in open source projects that are also licensed under the GPL. If on the other hand you want to use the project for a proprietary app where you don't want to open source the code, then you need a commercial license. The price for one developer is currently EUR 99. One year of updates is included
My understanding of the GPL is that you are not in a position to offer a commercial license that allows one to use this code in proprietary software because you are not the sole owner of this project's copyright.
You can read common answers to questions about the GPL here, and RMS talks specifically about selling exceptions in GPL software here.
My understanding (hopefully others can validate this point of view) is that you are able to sell a proprietary version of any software that has been licensed under the GPL if you own the copyright. There is no transfer or change in the status of ownership that occurs after licensing something under the GPL, and this means that you are at liberty to use any additional licenses that you like.
However, you are not able to sell a proprietary version that includes the contributions that others have made because they have only licensed you to use their code under the GPL. You do not own their contributions, they do, and they have licensed their code to you under strict terms which prohibit use in proprietary software.
If my understanding is correct, then you can either:
Additionally, on line 2 of fbs_runtime/signal_.py
the following code is used:
from PyQt5.QtNetwork import QAbstractSocket
Unless you have an agreement with Riverbank computing, you are not allowed to sell a version of their software that can be used in proprietary software. The FSF talks about linking to GPL software here and it may be worth seeking legal advice to ensure compliance in this regard - I've seen mixed opinions of this interpretation.
I'm not sure if this is currently possible but I would like the "version" field in the build/settings/base.json
to be the canonical version field I can reference across the app. Specifically, I would like to include the version value as part of the title window. Any ideas?
I'm trying to replicate this System tray & Mac menu bar example and I'm trying to figure out why I can't get the menu to work. I can see the tray icon, but I can't click on it. Short 10-sec video of the result.
Is there something I'm missing for initializing the tray menu?
from fbs_runtime.application_context import ApplicationContext, \ cached_property
import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class AppContext(ApplicationContext):
def run(self):
self.main_window.show()
self.tray_icon.show()
self.app.setQuitOnLastWindowClosed(False)
return self.app.exec_()
@cached_property
def icon(self):
return QIcon(self.get_resource('ice-cream-chocolate.png'))
@cached_property
def main_window(self):
result = QMainWindow()
result.setWindowTitle('Hello Test!')
result.resize(250, 150)
return result
@cached_property
def menuTray(self):
menu = QMenu()
action = QAction("A menu item")
action2 = QAction("Menu item 2")
menu.addAction(action)
menu.addAction(action2)
return menu
@cached_property
def tray_icon(self):
tray = QSystemTrayIcon()
tray.setIcon(self.icon)
tray.setVisible(True)
tray.setContextMenu(self.menuTray)
return tray
I would like to pass the version of my application into the NSIS compilation step, so that I will be able to produce a MyApp-v1.0.0-Setup.exe
or similar.
I see that you can pass arguments to makensis
so that these can be available inside of Installer.nsi
: http://nsis.sourceforge.net/How_can_I_let_the_compiled_script_depend_on_something_dynamic
What would be the best way to offer this ability?
Should create_installer_windows()
be able to accept a version
argument or should the installer
command be able to read the version optionally via e.g. python -m fbs installer 1.0.0
...?
Right now it only prints a message on finishing. Would be nice to have some progress indication as it can take a while even for the simplest of apps (actually I tried it with your excellent Qt for Python tutorial's chat application (BTW big thx for that, I'm still surprised how sparse the available resources to teach oneself PySide2 are))
I'm creating a Tutorial.app on macOS and I'm trying to figure out why I can't get shutil.which('someapp')
to work. It keeps returning None
whichever program I'm trying to look up if I run the frozen app. If I run the fbs app using python -m fbs run
, the shutil.which
returns the program path as expected.
I've also tried to write a custom "which" for my application, which checks for filenames on PATH which have os.access(fpath, os.X_OK)
... but this also won't return anything other than None
under the frozen mac .app.
PyInstaller actually has its own compatibility library which seems to include shutil.which
and an implementation of searching through PATH for executables (using os.X_OK
), so to me it kind of seems like it should work... 🤔
Any ideas?
First:
I am merely a developer who finds fbs interesting and is looking to create a small (FOSS) project using fbs.
The license of fbs is said to be GPL (version 3), however, the README states that:
In simple terms, this means you can use it for free in open source projects that are also licensed under the GPL. If on the other hand you want to use the project for a proprietary app where you don't want to open source the code, then you need a commercial license. The price for one developer is currently EUR 249. One year of updates is included. To obtain a license, click here.
It is to my understanding that the license GPL means that one can not redistribute a version of the software without also providing the source code for the modifications made to the software under GPL. This would mean that:
I suggest that the author change the license of fbs into a license compatible with his vision within the README, since GPLv3 to my knowledge is not compatible with said vision.
Regards,
Hans-Filip
If you are planning to have a showcase of apps/examples built with fbs, I'd like to add an open-source application I'm working on called openroll. It was built with Python, PyQt5 and fbs of course! Hope if can help anyone looking for setup/code examples when working with fbs. There is an official installer for Windows currently built using NSIS. Repository is found at saltycraig/openroll.
How do you create a Windows installer from Linux? I've installed the NSIS package as required, but fbs installer
insists on creating an installer for Linux...
I am importing serial.tools.list_ports
in my program and am receiving the error ImportError: No module named 'serial.tools'
when running the executable after cleaning and compiling with fbs freeeze --debug
. I have serial 0.0.70
installed.
I added serial
, serial.tools
, and serial.tools.list_ports
(only one at a time) to the settings/base.json
file in the hidden_imports
key.
I understand you are releasing your code under GPL. Which version of the GPL?
Before I try your app, it appears to be analogous to QtCreator .... do I have this correct? If so this is a developer tool, and not something I as a developer would ever release to a customer.
Now I read the prior discussion on licensing. Do I understand that your app injects your code into my code such that you can now claim license dominion? (QtCreator as far as I know does no such code injection).
If this is the case is your app still viable to produce an application that does not include your code?
Hi again Michael!
I've been bugging you so many times on this topic already, so I'll just keep it short. I really need to add custom paths to PyInstaller now via the --paths
option (which you made a little bit harder recently with v0.4.4) 😉 ... I guess my only option is to maintain my own version of each freeze_[platform]
function and on each fbs update I will have to do a diff check for changes.
I initially thought it could be possible to monkey patch the arguments of the functions to accept an args
argument again and then remove the initial args = []
declaration ... but I was unable to figure out a way to do this and asked at SO, but without much success so far.
Personally, I think it would make sense to allow for a .spec file in the settings. Let me know if this is something you think sounds okay and I can create a PR if you like.
Since I have been bringing this up many times, please close this request if you feel you cannot support this for whatever reason and I will have to deal with it. This is my final attempt to make you change your mind on allowing for this type of customization, I promise. 😉
Please let me know what your suggestion is, and I will then shut up about this.
Just wanted to say thanks for putting together the PyQt5 tutorial, I've been working on a video course that makes use of it (along with Tornado and RxPy) and it's nice to someone else working on promoting and educating developers about the Qt5 coding with Python.
The installer part is very interesting as PyQt5 itself also has an installer/deployer called pyqtdeploy, it would be neat in the future to see a comparison between fbs and pyqtdeploy.
Running python -m fbs run
works fine, but python -m fbs freeze
generates the following error:
(pyqt5_py35) C:\Users\iruser\code\repos\fbs-tutorial>python -m fbs freeze
Traceback (most recent call last):
File "C:\Users\iruser\AppData\Local\conda\conda\envs\pyqt5_py35\lib\runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "C:\Users\iruser\AppData\Local\conda\conda\envs\pyqt5_py35\lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "C:\Users\iruser\AppData\Local\conda\conda\envs\pyqt5_py35\lib\site-packages\fbs\__main__.py", line 4, in <module>
main()
File "C:\Users\iruser\AppData\Local\conda\conda\envs\pyqt5_py35\lib\site-packages\fbs\cmdline.py", line 17, in main
args.cmd()
File "C:\Users\iruser\AppData\Local\conda\conda\envs\pyqt5_py35\lib\site-packages\fbs\builtin_commands.py", line 35, in freeze
freeze_windows()
File "C:\Users\iruser\AppData\Local\conda\conda\envs\pyqt5_py35\lib\site-packages\fbs\freeze\windows.py", line 27, in freeze_windows
remove(path('${freeze_dir}/' + dll_name))
FileNotFoundError: [WinError 2] The system cannot find the file specified: 'C:\\Users\\iruser\\code\\repos\\fbs-tutorial\\target\\Tutorial\\python3.dll'
When I look inside of fbs-tutorial\target\Tutorial
, there's no python3.dll in there
. Only a python35.dll
.
As it is a python application, what about helping to deploy on pypi and conda ?
Hi,
Thanks for all the work you've put into fbs, the documentation has been really helpful! I ran into an issue now the first time I tried freezing my application, the frozen application won't start. I ran the following command to freeze the application (on Windows):
(pyqt_fbs) C:\Users\fredr\Documents\Code\list_scanner>python -m fbs freeze
This command produced no output.
When trying to run the produced target/CTMR list scanner/CTMR list scanner.exe
I get the following message in a small dialog window:
Window title: Fatal Error!
Content: (Yellow exclamation sign) Failed to execute script main
Button: OK
All code is available here: https://github.com/ctmrbio/list_scanner/tree/pyqt-fbs. There is a conda environment file in the repo to reproduce the environment I was using as well.
I don't really know where to start troubleshooting this, is there a log file for frozen applications or something like that?
I feel that it's difficult to follow the code of fbs since a lot of docstrings are missing. For example, there's no docstring on the ApplicationContext class.
I also have a hard time following why the application won't run if I remove the @cached_property from the application_context.py. I'm somewhat familiar with LRU cache, but not to the extent that I understand why your're using it in application_context.py.
In short; docstrings would help when digging.
Hi,
I've been using fbs to build .exe of my app for windows, and it's all been great so far!
I'm wrinting it using PyQt5, numpy, Pillow and a thing called pypylon (the rest are pure python libs).
While other packages are no issue it all, pypylon is giving me some serious headache.
And the bunch of dll's it comes with never go into the target/app
when I'm doing python -m fbs freeze
I managed to get it working by manually copying the all dll-s from site-packages/pypylon
into my target/app
, but would like to get some no-brainer automation here :)
After doing some investigation on my own it looks like fbs
has no capability of including such dll-s into the build manually. They also suggest messing with pyinstaller and I thought trying something like pyinstaller --paths
or pyinstaller --add-data
to see if it helps, but honesltly going down that level is not a thing I would like doing, yet I still have to discover a proper way to do so.
There was also an issue with hidden import with that library, but it works fine after adding this line into main.py
(just adding this in case you want play with it yourself)
from pypylon import _pylon, _genicam
Followed the manual of fman build system to place some resource files under src/main/resources/
. Then ran the python -m fbs freeze
command to copy the applicable files into my app's frozen directory inside the target/ folder. But found that all the resource files were not copied to the frozen directory.
Attached is the log of the debug output of python -m fbs freeze
.
freeze.log
This issue is not observed on Ubuntu 16.04LTS and Windows 10. I notice that there exists a directory txt2mobi3
containing pyc files in the frozen directories on MacOS, while there doesn't exist such a directory on Ubuntu and Windows. Note that the resource files are supposed to be copied to a subdirectory txt2mobi3/resources
.
You can find the source code at https://github.com/renweizhukov/txt2mobi3_app.
To repro this issue:
$ git clone https://github.com/renweizhukov/txt2mobi3_app.git
$ cd txt2mobi3_app
$ pip install -r requirements.txt
$ pip install PyInstaller
$ python -m fbs freeze
MacOS version:
ProductName: Mac OS X
ProductVersion: 10.12.6
BuildVersion: 16G1618
Please let me know if you need any other info. Thank you very much for the help!
Hello there,
I'm quite interested by this project but I would like to know if there is any plan to support "Qt for python" in the future or if this tool will remain PyQt specific.
Thanks
This may sound weird, but do you think it's possible to bundle the python binary itself (e.g. python.exe on Windows)?
I know how to bundle multiple binaries which stem from python scripts... But the python binary itself?
Any ideas?
When there is no internet or the installer is blocked by a firewall, the installation aborts without offering an offline install option.
1: Error text is unhelpful: "Unable to connect to the internet. If you use a firewall, please white list fmanUpdate.exe" (Do I have to whitelist each new installer? What if I'm not the admin of the firewall, as often happens on corporate networks?)
2: Help button leads to an Error 404
3: There's no link in the installer or on the website to download an offline installer.
Feature request: it would be useful to actually allow some applications to be frozen with --windowed
, but also allow other applications to show this window. Could you add an option somewhere for this?
EDIT: I may add that when you produce binaries using setup.py
(when bundling a .whl), you get the option to make such binaries run as console_scripts
(windowed) or gui_scripts
(not windowed). In my past experience, I've actually had some issues with some Python scripts using PySide and being renamed to ".pyw" (Windows feature only), which will cause them to run in a non-windowed mode. I'm not sure how related this .pyw approach is to the setup.py
or PyInstaller approach though.
fbs lets us create .deb packages for Ubuntu... but Ubuntu is Debian based and using a Debian system returns an error :
Unsupported Linux distribution
The doc is not clear but we must add in src/build/settings/base.json the line :
{
...
"installer": "Ubuntu"
}
A way to made fbs working on Debian :
In fbs_runtime/platform.py :
def is_ubuntu():
try:
linux_distrib = linux_distribution()
return linux_distrib == 'Ubuntu' or linux_distrib == 'Debian'
except FileNotFoundError:
return False
Perhaps renaming is_ubuntu() in is_debian_like() would make more sense.
In any case, thanks for your job !
Hi @mherrmann,
I noticed that after an update of fbs to the current v0.3.9, my NSIS changes were lost and the installer got built using the defaults. This seems to happen because the Installer.nsi
is now expected to be found insrc/installer/windows
(by judging from the contents of windows.json
in this repo). I used to store this in src/main/NSIS/Installer.nsi
. So I moved my Installer.nsi to src/installer/windows/Installer.nsi
instead. But now I got an error instead, where fbs.builtin_commands.installer()
does not find the Installer.nsi file at all:
subprocess.CalledProcessError: Command '['makensis', 'Installer.nsi']' returned non-zero exit status 1.
I previously did not use a windows.json
at all, but now I tried placing one in the src/build/settings/windows.json
in order to tell fbs where to find Installer.nsi. The contents is the same as the one in this repo:
{
"installer": "${app_name}Setup.exe",
"resources_to_filter": [
"src/installer/windows/Installer.nsi"
]
}
Still getting the same error as before though, where the Installer.nsi is not found and I cannot make the installer.
I got curious and wanted to check if anything had also changed in src/build/settings/base.json
. I can see that it differs quite a lot from my own base.json and this got me wondering... what happened to the json keys app_name
, main_module
and author
?
Are these keys no longer used and if so, where do I specify the entry point of main_module
for example?
If I remove the main_module
key/value from base.json, fbs -m fbs run
will no longer work.
Lots of confusing changes here. Did I miss some kind of memo? 😉
İnstaller configration required Settings Author Name but
fbs/fbs/installer/windows/__init__.py
Line 13 in 86d915d
Author missing in fbs-tutorial base.json
https://github.com/mherrmann/fbs-tutorial/blob/d34ebfdbf3e36f4c3a580f90d6c55653d3dfc710/src/build/settings/base.json#L2
The website claims packaging for Linux is supported but I get "Unsupported OS" when trying to package on Ubuntu.
Hi interesting project, almost considered following your advice and choosing QT over electron.
However, once you get used to the productivity of HMR (hot module reloading) in the javascript world, and MVVM frameworks like Vuejs, it's hard to switch, even if it means saving your users a few seconds on load time.
Thoughts?
I'm looking to pass extra arguments to pyinstaller for my main app.
Right now, I'm using a build.py script which I execute like so: python build.py freeze_all
In my freeze_all
function, I have the fbs.builtin_commands.freeze
function to build my main app. But the builtin_commands.freeze
function does not accept any arguments. I'm noticing that that freeze_windows
, freeze_mac
, freeze_arch
, freeze_linux
already takes the extra_pyinstaller_args
argument, but the fbs.builtin_commands.freeze
function does not. So in my mind, a very quick fix for this would be to make the fbs.builtin_commands.freeze
function accept a new extra_pyinstaller_args
argument which would be passed on to the freeze_windows
, freeze_mac
, freeze_arch
, freeze_linux
functions.
I wouldn't mind whipping up a PR if you think it's a good idea.
The background to why I am looking to do this is I wish to add a hooks folder, which I ideally want placed in my project's root (not in src/main/python). I would then want to pass the --additional-hooks-dir
as an extra pyinstaller argument when building the main app.
Michael, I first want to thank you again for making fbs possible and helping me convert my app to it. I have an issue with my frozen app. Since I’m trying to make an app that blocks certain websites using the hosts file (I’m doing it for Mac first) my app needs root privilege. I have added a function to my main.py script that relaunches the app/script with root privileges. It works when I run the app, but after I freeze it it doesn’t - it get’s stuck in a loop and just relaunches itself everytime asking for the password.
Here's my code for relaunching main.py :
if getattr(sys, 'frozen', False):
# If the application is run as a bundle, the pyInstaller bootloader
# extends the sys module by a flag frozen=True and sets the app
# path into variable _MEIPASS'.
application_path = sys._MEIPASS
else:
application_path = os.path.dirname(os.path.abspath(__file__))
print(application_path)
def _elevate():
"""Elevate user permissions if needed"""
if os.getuid() != 0:
_mac_elevate()
else:
pass
def _mac_elevate():
"""Relaunch asking for root privileges."""
print("Relaunching with root permissions")
applescript = ('do shell script "python '+application_path+'/main.py"'
'with administrator privileges')
exit_code_1 = subprocess.call(['osascript', '-e', applescript])
sys.exit(exit_code_1)
if __name__ == '__main__':
_elevate()
appctxt = AppContext()
exit_code = appctxt.run()
sys.exit(exit_code)
This is the changed function (using sys.executable for relaunching) that I'm trying to get working when the app is freezed :
def _mac_elevate():
"""Relaunch asking for root privileges."""
print("Relaunching with root permissions")
applescript = ('do shell script "open '+ sys.executable +'"'
'with administrator privileges')
exit_code_1 = subprocess.call(['osascript', '-e', applescript])
sys.exit(exit_code_1)
The whole code is in this repository - https://github.com/Sakelariev/information-diet/tree/master/Diet2
What am I doing wrong? Any help would be very appreciated :)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.