Examples

distbuilder logo

Source Code / Resources

All of the examples discussed here are included in the "source distribution" of the library. The PyPi downloads page for this project is arguably the fastest route to acquire that. See From source installation to learn about other ways of downloading these files.

Hello World Example

The Hello World Example is a simple demonstration of using the PyToBinPackageProcess class. This is one of the most straightforward, simple use cases for the library.

If you did not download the full source for the library (inclusive of the examples) you may download/copy the following individual files directly from GitHub into a local directory. It is recommended that you place them in a directory named hello_world.

Start by confirming you can run the program script in the "natural" manner:

python hello.py

Don't expect it to do much... It simply writes "Hello World!" to the console.

Now, run the build script:

python build.py

The build script should achieve the following:

  • converts the Python script to a stand-alone executable binary
  • bundles the example resource (license file) into a directory with the binary
  • compresses the distribution into a simple zip file (left in the same directory as the source)

Having witnessed that function, review the build.py script for yourself. It should be self-explanatory for a moderately seasoned Python developer.

Hello World Tk Example

This next example is a more comprehensive version of the first Hello World. It is a demonstration of using the PyToBinInstallerProcess class.

Note: This example requires the standard Python TKinter library be installed.

You may download/copy the following individual files directly from GitHub into a local directory.
It is recommended that you place them in a directory named hello_world_tk.

Start by confirming you can run the program script in the "natural" manner:

python hello.py

The program is a single button GUI. Clicking the button writes "Hello World!" to the console.

Now, run the build script:

python build.py

The build script should achieve the following:

  • obfuscates the code (to mitigate the risk of reverse engineering)
  • converts the obfuscated version of the source to a stand-alone executable
  • builds a full installer with the executable bundled into it
  • moves the installer to your desktop (for convenience)
  • launches the installer (for testing)

Proceed through the installer, and then run the program to confirm it works.

Having witnessed everything function, review the build.py script. The script is a simple example, but covers a good portion of the "core" distbuilder features.

Feature spotlight: "file name normalization"

You might notice that binary names/paths (in any of the examples) may or may not include extensions such as .exe. Likewise, icons may or may not have extensions such as .ico specified. Yet, these scripts work cross platform, where the extensions differ! That is due to the use of normBinaryName and normIconName functions under the hood of distbuilder's processes. The library corrects those names for you automatically based upon the environmental context.

Currently, alternate icon resources must be provided which align with the platform context. There are plans, however, for future releases of the library to generate missing icon formats for you as needed.

Extended feature demo: "debug mode"

Here is a good place to illustrate one very useful extended feature of this library, which may prove immeaditely valuable to you. This is will also help you to understand a common pattern for using some of the primary distbuilder classes.

Locate the following commented out line in the Hello World Tk build script:

#def onPyPackageProcess( self, prc ): prc.isTestingExe = True

Uncomment that, and run the build process again. In the middle of the process, the standalone binary will be run for you in "debug" mode. Upon closing the program, the rest of the build process will continue.

This code demonstrates a design pattern employed by the "high level" process classes in distbuilder. That pattern is for a high level class to generate a "configuration object", or a lower level "process object", automatically set it up for the client implementation, and then "pass it through" an overridable function where you may access such and revise it for your own needs prior to its use.

So, what's the point of setting prc.isTestingExe = True ? If you have run this example program, the most astute observer may notice (on Windows or Mac, but not Linux...) that the stdout/err messages (seen by clicking the "Hello Tkinter" button when running the raw .py script) are not produced on the terminal by the standalone version of the program when it is launched in the normal manner. That is due to a feature of PyInstaller (and/or by additional platform details regarding standard output streams) to "swallow" console messages produced by gui applications. That may be desired behavior for a public release, but it may be also be highly counterproductive for debugging, since there are times when the standalone version may require specialized coding to make it work correctly in that context compared to how it did as a basic .py script. As such, distbuilder has included a solution for this, as demonstrated here. Refer to Testing for more details.

Hello Silent Example

It is another demonstration of using the PyToBinInstallerProcess class.

Hello Silent demonstrates how one can use distbuilder to build "silent" installers. These do not require user interactions for them to complete their tasks. Instead, they run automatically, while having the same flexible options present in the gui installers made available via command line arguments.

"Silent" installers built by distbuilder provide a very important additional feature.
They are able to be run in non-gui contexts, such as on "headless servers". Silent installers are, of course, also desirable (on any platform) for mass installation purposes such as when a network administrator needs to install the same program on countless workstations.

Building a silent installer requires nothing more than setting the isSilentSetup configuration option to True. As such, you can easily define a full blown packaging and installation process that could be run in Windows (for example) using an interactive graphical interface, AND could also be used on a CentOS server (for example), with nothing but a terminal interface available. You would only have to toggle the isSilentSetup option before running the build script!

This example expects that you already downloaded the first example (Hello World). That must be present in the testing environment within a directory adjacent to where you place the next file. That first directory must be named hello_world for this "master" script (which draws upon that) to function.

You may download/copy the example file directly from GitHub (into a hello_silent directory):

Build script: build.py

Upon building the silent installer, the demo is set to test "Auto Installation" of it. With that enabled, it will run the installer with the command line argument to "force installation". If run more than once, that option will cause it to uninstall any prior existing installation rather than exiting with an error, as it would do by default when a conflict was detected.

For more information, refer to Silent Installers.

Hello Packages Example

The Hello Packages Example is a demonstration of using the RobustInstallerProcess class. It demonstrates a way that you can generate and then "combine" multiple "packages" into a single installer with a single build process. In this case, those become separate components which may be installed selectively by the end user.

This example requires that both of the first examples (Hello World & Hello World Tk) be present in the testing environment within directories adjacent to a third directory where you place the next file. Those first two must be named hello_world and hello_world_tk for this "master" script to function.

You may download/copy the example file directly from GitHub (into a hello_packages directory):

Build script: build.py

Hello Merge Example

This is another demonstration of using the RobustInstallerProcess class.

Similar to the Hello Packages Example, Hello Merge demonstrates how you can "merge" multiple "packages" into a single package within an installer. The content of the two programs, which worked independently, will become one component which may NOT be installed selectively by the user.

This example requires that both of the first examples (Hello World & Hello World Tk) be present in the testing environment within directories adjacent to a third directory where you place the next file. Those first two must be named hello_world and hello_world_tk for this "master" script to function.

You may download/copy the example file directly from GitHub (into a hello_merge directory):

Build script: build.py

The key points to this example are to demo the implementation of the
onPackagesStaged virtual function of RobustInstallerProcess. Within that, QtIfwPackage list manipulation is shown (by default) via mergeQtIfwPackages. If you comment that line out, and uncomment the call to nestQtIfwPackage below it, you may test the results of these alternate ways to combine packages.

The demo goes on to show low-level manipulations, and regenerations of the files produced by, QtIfwConfigXml and QtIfwPackageXml objects to give you further insight into the design patterns and functionality of the library.

Hello Installer UI Example

A QtIwf installer is extremely customizable. In addition to simply copying files to another machine, it can perform extended operations on that target to further refine the environment where the program will run. Not only that, but the installer's interface, and logic flow, can be manipulated to precisely fit your use case. This example demonstrates a proof of concept modification to that UI.

This example requires the Hello World Tk files be present in the testing environment within a directory adjacent to where you will place the build script for this one. That required folder must be named hello_world_tk for this "master" script to function.

You may download/copy the example file directly from GitHub (into a hello_qtifw_ui directory):

Build script: build.py

The demo shows how one may assign the ifwUiPages attribute of a ConfigFactory to to easily add or replace default installer "pages" / "screens" with custom definitions. Those pages are represented using QtIfwUiPage objects.

The QtIfwUiPage class is designed with the expectation that you may wish to create custom pages using the Qt Designer WYSIWYG tool. Alternatively, your needs maybe met by employing a derived class e.g. QtIfwSimpleTextPage, which draws upon a built-in library resource file for the page layout.

In concert with altering these visual dimensions of the user experience, you may revise the logic via Installer Scripting, or call upon the higher level script abstraction classes QtIfwControlScript or QtIfwPackageScript.

Hello Wrapper Example

This example provides a collection of demonstrations using the QtIfwExeWrapper class. A "wrapper" can super impose environmental conditions on the context within which the binary is run. Notably, this may include an ExecutableScript for maximum flexibility. Follow the links to learn to more.

This example requires that both of the first examples (Hello World & Hello World Tk) be present in the testing environment within directories adjacent to a third directory where you place the next set of files. Those first two must be named hello_world and hello_world_tk for this "master" script to fully function.

You may download/copy the example files directly from GitHub (into a hello_wrapper directory):

Build script: build.py

GUI app: hello_gui.py

Terminal app: hello_terminal.py

Within the build script, select a particular example to test and uncomment its p.run() line. Then, run the script to see the results.

In conjunction with choosing a wrapper feature to test, you may switch between a gui and non-gui context. To do so, swap the commented out lines in the ConfigFactory attributes. That is, near the top of the script change:

f.isGui            = True        
f.entryPointPy     = "hello_gui.py"

To:

f.isGui            = False 
f.entryPointPy     = "hello_terminal.py"

When the resulting app is run, it will show the effect of implementing the various wrapper features e.g. the arguments the program received, or if you are running in an "elevated" context, etc.

If desired, you may also wish to test running these demo programs post installation in "debug mode". See the documentation on the run function.

Hello World Qt Example

The Hello World Qt Example demos the Qt C++ Integration feature. If you wish to review / test the code, it is strongly recommended you read that section of the documentation in its entirety.

Hello World QML Example

See Hello World QML Example

Hello World QML New Example

See Hello World QML New Example