Using ttk with Py2App - python

I'm trying to figure out how to use Py2App to make one of my scripts less user hostile. The script is written using Tkinter using "notebook" from ttk, and I can't figure out how to include the ttk thing! It compiles as it should but when I try to run I get a console error: _tkinter.TclError: can't find package tile.
The problem can be replicated with:
test.py
#!/usr/bin/python2.7
from Tkinter import Tk
from ttk import Notebook
if __name__ == '__main__':
gui = Tk()
gui.wm_title("Py2App testing")
gui.wm_minsize(450, 300)
main = Notebook(gui)
main.pack(fill='both', expand='yes')
gui.mainloop()
I use a simple file which looks like:
setup.py
from setuptools import setup
APP = ['test.py']
DATA_FILES = []
OPTIONS = {'argv_emulation': True,}
setup(
app=APP,
data_files=DATA_FILES,
options={'py2app': OPTIONS},
setup_requires=['py2app',],
)
I've tried a number of combinations of 'packages': ['ttk'], 'includes': ['ttk'],, setup_requires=['py2app', 'ttk'],, but I can't get it to work so I figured maybe someone can explain how this actually works! =)
I don't know about tile either, how do I include that?

Related

cx_freeze debugging console?

I try to build my (fine working) python 3.6 tkinter gui app to a windows excecutable. After hours of trial an error (with some name and dll issues) I got it to run. But it seems to have varoius of bugs. Some functions seem not to work and I have no console output of the produced error... is there a way to debug the exe?
this is my setup.py
import sys
from cx_Freeze import setup, Executable
import os
os.environ['TCL_LIBRARY'] = r'C:\Users\xxx\AppData\Local\Programs\Python\Python36\tcl\tcl8.6'
os.environ['TK_LIBRARY'] = r'C:\Users\xxx\AppData\Local\Programs\Python\Python36\tcl\tk8.6'
base = None
if sys.platform == 'win32':
base = 'Win32GUI'
executables = [
Executable('myApp.py', base=base)
]
build_exe_options = {"packages": ["tkinter",
"PIL",
"savReaderWriter",
"numpy",
"scipy",
"os"],
"include_files": ["tcl86t.dll",
"tk86t.dll"]}
setup(name='myApp',
version='0.1',
description='some description',
options = {'build_exe': build_exe_options},
executables=executables
)
myApp.py
is too big to post it here. This is a snippet that only works 'unfreezed'. You need an spss.sav file like this to try this out.
from tkinter import *
from tkinter import ttk, filedialog, messagebox
from PIL import Image, ImageTk, ImageDraw
from savReaderWriter import SavReader
import numpy as np
from scipy.ndimage import gaussian_filter
import os
class MyApp:
spss_file = None
def import_spss(self, *args):
filename = filedialog.askopenfilename()
if filename:
try:
with SavReader(filename, returnHeader=True, ioUtf8=True) as reader:
spss_file = reader.all()
self.spss_file = np.array(spss_file)
except Exception as ex:
messagebox.showinfo(title="Import SPSS File",
message="Warning: wrong file format chosen! \nAccepted formats: sav")
print(ex)
return
else:
return
def main():
App = MyApp()
App.import_spss()
print("everything works fine")
main()
if you want the console window to appear, after it is frozen, just remove this code from the setup script:
if sys.platform == 'win32':
base = 'Win32GUI'
what that code does is it tells cx_Freeze to have the console window not show up, after frozen. this is only required on windows, because on other OSes,it depends on whether or not it was run from a terminal. make sure though, when you have finished debugging it, to put that code back in, or the console window will show up in your app.
by the way, one of the most annoying problems I've ever had was when making a program with tkinter and cx_Freeze. the problem was that it was starting in the wrong directory and not able to find the TK Dll. If when you run this with the console, and you see something about a file not found, chances are you are not including it or it is in the wrong directory.
have a good day!

(Python3.4) tkinter messagebox not work when it executed by cx_freeze

import sys
from cx_Freeze import setup, Executable
build_exe_options = {'packages': ['os','tkinter','random',
'heapq','collections','sys','pickle']}
base = None
if sys.platform == "win32":
base = "Win32GUI"
setup( name = 'Game',
version = '0.02',
description = 'My GUI application!',
options = {'build_exe': build_exe_options},
executables = [Executable('Game.py', base=base)])
here's the code of the setup
from tkinter import *
value_a = 'hahaha'
a =messagebox.showinfo('laugh',value_a)
and the code that would executed
the erorr is Nameerorr : name "messagebox" is not defined when I typed python 123.py build or python haha.py build in cmd
I already used import *, if I run the code it shows message but neither in cmd nor .exe
Should I use import tkinter as tk? But it is difficult to read my code by adding "tk", I want to keep import * so that no "tk.xxx" is needed and it will still works on exe.
from tkinter import * does not work for messagebox, so you must import the message box individually like below
from tkinter import messagebox
I had this problem too. It worked OK in the IDE but not in direct run mode.
Adding import tkinter.messagebox as messagebox fixed the problem.
Thanks, G.

cx_Freeze flashes a cmd window even using Win32GUI

I am new to cx_Freeze.
I started using it in a big python application. That application is using PySide and uses multiprocessing. On application start and each time a thread starts I see a cmd window flashing shortly (just open and close really quick.. no time to read anything).
Now I tried with a very simple application. Like this:
import os
import sys
import multiprocessing
from PySide import QtGui
from PySide import QtCore
from PySide import QtNetwork
if __name__ == '__main__':
# multiprocessing support
multiprocessing.freeze_support()
# init application
app = QtGui.QApplication.instance()
if not app:
app = QtGui.QApplication(sys.argv)
QtGui.QApplication.setQuitOnLastWindowClosed(False)
# check systemtray
if not QtGui.QSystemTrayIcon.isSystemTrayAvailable():
QtGui.QMessageBox.critical(None, "Systray", "I couldn't detect any system tray on this system.")
sys.exit(1) # quick kill
wid = QtGui.QWidget()
wid.resize(250, 150)
wid.setWindowTitle('Simple')
wid.show()
sys.exit(app.exec_())
But this is still showing and flashing a window on start.
Here is the setup file I use with this:
from cx_Freeze import setup, Executable
# dependencies
build_exe_options = {
"packages": [#"os", "sys", "glob", "re", "atexit",
"PySide.QtCore", "PySide.QtGui", "PySide.QtXml", 'PySide.QtXml',
'xml', 'P4', 'MYRefs_module', 'MYUtils_module', 'logging',
'multiprocessing'],
# "include_files": mfiles, # this isn't necessary after all
"excludes": ["Tkinter", "Tkconstants", "tcl"],
"build_exe": "build",
"icon": "img/icon.ico",
"include_msvcr":True
}
executable = [
Executable("main.pyw",
base="Win32GUI",
initScript = None,
targetName="Example.exe",
targetDir="build",
copyDependentFiles=True,
)
]
setup(
name="Example",
version="0.1",
description="Example", # Using the word "test" makes the exe to invoke the UAC in win7. WTH?
author="Me",
options={"build_exe": build_exe_options},
executables=executable,
requires=['PySide', 'cx_Freeze', 'P4', 'xml']
)
May be I am doing something wrong? Is the multiprocessing support the issue? Any hint appreciated.
Btw, I am using python 2.7.3x64 and cx_Freeze 4.3.4, PySide 1.2.2 ...
solved.
And after finding the problem, the question was probably not right.
I catch a os.system('rd /s /q somefolder') call. In one of my modules loaded.
As soon as I remove that, which is not necessary right now, the console window flashes dont show again.
I used it in one single place, but the flashes appeared in several places (threads). I used as well Popen, which apparently works fine.

'Font not defined' in Tkinter application freezed by cx_Freeze

I have freezed a Tkinter-using GUI Python 3.4 app with cx_Freeze and when I tried to run it, I was presented the following error:
NameError: name 'font' is not defined.
When I remove all references to font from my code (i. e., if I don't set ttk Label fonts anywhere In the code), it works just fine and the exe runs nicely. I have checked the library.zip archive created by the freeze script and it does contain the font.pyc file in the tkinter directory.
This is what my setup.py file looks like:
import cx_Freeze
import sys
import tkinter
base = None
if sys.platform == 'win32':
base = "Win32GUI"
executables = [cx_Freeze.Executable("rocnikovka.py", base=base)]
cx_Freeze.setup(
name = "Number evolution",
options = {"build_exe": {"packages":["tkinter", "tkinter.font"], "includes": ["tkinter", "tkinter.font"]}},
version = "0.01",
description = "Rocnikovka",
executables = executables
)
Any help is appreciated.
UPDATE: I have also tried making an executable out of the script with py2exe but ended up with the same result. Seems like a problem with tkinter rather than with cx_Freeze.
UPDATE #2: I import tkinter and ttk in the script like this:
from tkinter import *
from tkinter import ttk
I have a few fonts defined in the script, like this one:
font_title = font.Font(family = "Exo 2", size = 20, weight = "bold")
which I then use as the font parameter of ttk.Label objects.
This all works just fine when run as a script in IDLE.
Thanks to Arden, I was able to get it to work adding an explicit font sub-module import:
from tkinter import font
Works perfectly good now.

py2app plist app info not showing up when looking at About app

I'm trying to create an App using py2app and everything is working fine except that I can't get the info from my specified plist to show when I select the About section from the menu. The information shows up when I right click and select Get Info, but not inside the app. When I click on About TextTools (the name of my app) I'm shown the info for Tcl/Tk instead.
Here's what I'm getting:
Here is my setup.py file:
"""
This is a setup.py script generated by py2applet
Usage:
python setup.py py2app
"""
from setuptools import setup
APP = ['TextTools.py']
DATA_FILES = ['TextAnalysis.py', 'CustomText.py', 'ResultTree.py']
OPTIONS = {'argv_emulation': True,
'iconfile': '/Users/howe1rp/Desktop/TT_local/TextTools_local/TextTools/man.icns',
'plist': {
'CFBundleName': 'TextTools',
'CFBundleShortVersionString':'0.0.1',
'CFBundleVersion': '0.0.1',
'CFBundleIdentifier':'com.rh.TextTools',
'NSHumanReadableCopyright': '# My Name 2014'}}
setup(
app=APP,
data_files=DATA_FILES,
py_modules=['TextAnalysis', 'CustomText', 'ResultTree'],
options={'py2app': OPTIONS},
setup_requires=['py2app'],
)
It looks like you are using Tkinter within your Python app. The Cocoa-based Aqua Tk on OS X creates the base menu options and includes a default About menu item. It is not documented very well in Tk, but it is possible to override the default Cocoa About by overriding the default Tk tkAboutDialog command. Here's a very simple example which uses the built-in Aqua Tk standardAboutPanel.
try:
from tkinter import * # Python 3
except ImportError:
from Tkinter import * # Python 2
def new_file():
# ...
pass
def about_dialog():
root.tk.call('tk::mac::standardAboutPanel')
root = Tk()
win = Toplevel(root)
menubar = Menu(win)
menu_file = Menu(menubar)
# ...
menubar.add_cascade(menu=menu_file, label='File')
# ...
menu_file.add_command(label='New', command=new_file)
# ...
root.createcommand('tkAboutDialog', about_dialog)
win['menu'] = menubar
root.mainloop()
There's more info here.
Thanks a lot for this great answer. I've seen that you added some additional menu bar entries to your code, not only the "About" panel. If all you want is to provide a custom "About" panel, here is the stripped down Python 3 version.
from tkinter import *
def about_dialog():
root.tk.call('tk::mac::standardAboutPanel')
root = Tk()
root.createcommand('tkAboutDialog', about_dialog)
root.mainloop()

Categories