Python tkinter exe файл

Pyinstaller + tkinter = issues ?

Although this blog explains .py to .exe conversion using a tkinter app example the instruction can be followed with minimal changes for any other type of Python application.

Some basic assumptions before we start :

  • You can code intermediate level in Python, which obviously you must be hence you are getting such issues.
  • You have Pyinstaller, tkinter(with its dependencies) already installed on the system.
  • You have fully functional tkinter app which you can directly run from python, no worries if not just copy paste below code to python file and save it as “ListControlTest.py” in your python workspace folder say henceforth referred to as “UIToEXE“.
import tkinter import TkTreectrl def main(): root = tkinter.Tk() root.title('Simple MultiListbox demo') mlb = TkTreectrl.MultiListbox(root) mlb.pack(side='top', fill='both', expand=1) tkinter.Button(root, text='Close', command=root.quit).pack(side='top', pady=5) mlb.focus_set() mlb.config(columns=('Column 1', 'Column 2')) list1 = [['123', 'abc'], ['456', 'xyz'], ['678', 'pqr']] for row in list1: mlb.insert('end', *row) root.mainloop() if __name__ == '__main__': main()

Note : This program uses TkTreectrl package which you need to install separately and is not part of default tkinter package. How to install that ? we’ll that could be a topic for another post. But the reason this blog is using such a example is because these custom Tkxxxx package are called tcls or extensions which create nasty problems while converting to .exe.

Читайте также:  Apt get install numpy python

Ok all set, so lets start digging answers for those questions…

How to compile tkinter app to .exe ?

  1. Open command prompt in your UIToEXE folder, workspace folder, and run following command : pyinstaller ListControlTest.py
  2. Now this will generate a “ListControlTest.spec” file in same folder as script and some processing is going on.
  3. Now this may sound weird but as soon as the .spec file is generated kill the command prompt. Reason, we’ll be using this .spec file to configure all additional parameters and to generate our .exe file. This .spec file is gonna be our best buddy for the course of this blog. Content of spec file will be something like this :
# -*- mode: python -*- block_cipher = None a = Analysis(['ListControlTest.py'], pathex=['C:\\your_path_to_workspace_folder\\UIToEXE'], binaries=[], datas=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='ListControlTest', 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, name='ListControlTest')

This will generate “build”, “dist”, “_pycache_(if you are usging python 3.5 and above)” directories in workspace folder. Now the “dist” folder will contain all required files necessary* to run the exe and The ListControlTest.exe as well. There you have it you just converted your .py application to a standalone exe. But don’t bother running it, it wont work. If you run it now it throw some error and close immediately without you getting to see what the error was.

* – Ideally, but not in this case.

Idea : Start that exe from a command prompt and you’ll see the output error it throws.

Читайте также:  Top location href html

Ok, now how to fix that … well that’s our next question.

Note : During the course of this blog we are gonna build/generate our exe using command similar to above, it would be wise to always delete “build”, “dist”, “_pycache_” folders prior to proceeding.

How to resolve error like while running .exe generated using pyinstaller : _tkinter.TclError: can’t find package xxx ?

Ok now this is a bit tricky part, you would need to put on your Sherlock cap and hunt for few folders belonging to tkinter extensions dependencies.

  1. Now, In our demo script we use “TkTreectrl.MultiListbox” this internally uses another dependency “treectrl” which is missing and hence when we try to run our exe it throws this error : _tkinter.TclError: can’t find package treectrl
    Hey, hey, hey …. cool down, you might get some other error so you need to find that dependency’s folder …. this is why i asked you to put-on that Sherlock cap in first place.
  2. Now these tcl extensions are normally present in your “\Lib\site-packages” folder in this case we are looking for “treectrl” that is present in ” \Lib\site-packages\treectrl2.4.1” directory.
  3. Now we need to edit our .spec file created previously to account for these additional dependencies.
  4. So open that file in a editor and customize it as followed :
hiddenimports = [ "tcl", "tkinter", "TkTreectrl" ] datas = [ ("Python_Installation/Lib/site-packages/treectrl2.4.1/*.*", "./tcl/treectrl2.4.1") ] a = Analysis(['ListControlTest.py'], pathex=['C:\\your_path_to_workspace_folder\\UIToEXE'], binaries=[], datas=datas, hiddenimports=hiddenimports, hookspath=[], runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher, noarchive=False)

Now, Lets see whats changed in .spec file. we added a variable “datas” and then passed it to the “Analysis” function, which initially had empty list. now as per pyinstaller’s documentation “datas” list is used to provide a list of tuple which contain path_from and path_to additional data files dependencies. So we provide our “treectrl‘s” extension files and set to path relative to .exe. For tcl it should be “./tcl/treectrl2.4.1“.

  • Now, run following command again in a command prompt opened in UIToEXE folder : pyinstaller ListControlTest.spec
    This time voila the exe works !
  • But hey whats that nasty console window opened behind the UI, well thats because the tkinter UI is opened by the python script running in that console. But can’t we somehow remove that and just have our nice looking UI …. that’s our next question.

    How to show only tkinter UI without console in a pyinstaller .exe ?

    1. This one is pretty simple one just make one following change in .spec file : console=False in the “EXE” function of the .spec file.
    2. Now, run following command again in a command prompt opened in UIToEXE folder : pyinstaller ListControlTest.spec
      This time voila the exe opens without the console !

    Great we got our .exe running standalone without the ugly console in behind, but this “dist” folder is still a big mess. So many files which needs to be distributed along with our .exe. Isn’t there a way to make this distribution/installation of our .exe more manageable …. you guessed it correctly we are moving to our final question.

    How to generate single file .exe using pyinstaller ?

    For this we need to modify the .spec file to reflect single .exe creation instead of bundle folder. we can modify the .spec manually but it would be better the just regenerate the .spec file using pyinstaller again.

    1. For this we will re-visit step 1, 2, 3 of our first question but the initial command needs to be modified as :
      pyinstaller ListControlTest.py —onefile —windowed —clean
    2. Same as step 3 above we kill the command as soon as the .spec file is generated.
    3. Now we modify the .spec file again with all our previous changes we made during our other questions. The Final content should look like :
    # -*- mode: python -*- block_cipher = None datas = [ ("Python_Installation/Lib/site-packages/treectrl2.4.1/*.*", "./tcl/treectrl2.4.1") ] a = Analysis(['ListControlTest.py'], pathex=['C:\\path_to_workspace_folder\\UITOEXE'], binaries=[], datas=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, a.binaries, a.zipfiles, a.datas, [], name='ListControlTest', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, runtime_tmpdir=None, console=False )

    Note : Although, this last step generates a single .exe, the exe is a self extracting .exe, that means everytime you run it it will extract the required files in temp directory execute the script then on close delete temp directories. Point to note here is this .exe may run little slower than the bundled folder .exe.

    Thanks for the patience going though this blog, I hope if not fully helped at-least this gave you some pointers to conquer your questions.

    Источник

    Converting Tkinter program to exe file

    Let us suppose that we want to create a standalone app (executable application) using tkinter. We can convert any tkinter application to an exe compatible file format using the PyInstaller package in Python.

    To work with pyinstaller, first install the package in the environment by using the following command,

    Once installed, we can follow the steps to convert a Python Script File (contains a Tkinter application file) to an Executable file.

    Install pyinstaller using pip install pyinstaller in Windows operating system. Now, type pyinstaller —onefile -w filename and press Enter.

    Now, check the location of the file (script file) and you will find a dist folder which contains the executable file in it.

    When we run the file, it will display the window of the tkinter application.

    Example

    In this example, we have created an application that will greet the user with their name by displaying the message on the screen.

    #Import the required Libraries from tkinter import * from tkinter import ttk #Create an instance of tkinter frame win = Tk() #Set the geometry of tkinter frame win.geometry("750x250") #Define a function to show a message def myclick(): message= "Hello "+ entry.get() label= Label(frame, text= message, font= ('Times New Roman', 14, 'italic')) entry.delete(0, 'end') label.pack(pady=30) #Creates a Frame frame = LabelFrame(win, width= 400, height= 180, bd=5) frame.pack() #Stop the frame from propagating the widget to be shrink or fit frame.pack_propagate(False) #Create an Entry widget in the Frame entry = ttk.Entry(frame, width= 40) entry.insert(INSERT, "Enter Your Name") entry.pack() #Create a Button ttk.Button(win, text= "Click", command= myclick).pack(pady=20) win.mainloop()

    Now, run the above command to convert the given code into an executable file. It will affect the directory (dist folder) where all executable file will be placed automatically.

    Output

    When we run the exe file, it will display a window that contains an entry widget. If we click the «Click» button, it will display a greeting message on the screen.

    Источник

    Оцените статью