Python Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsProgramming LanguagesPython Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old July 28th, 2004, 09:41 AM
elesys elesys is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jul 2004
Location: Atlanta
Posts: 5 elesys User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
Send a message via Yahoo to elesys
py2exe and tkinter not working well together

Hello everyone, please forgive if this topic already covered. I searched all forums and do not believe this particular variation of the topic has been addressed.

I have written a Python program that executes under Python. I want to distribute it to coworkers as a stand-alone; all of us using WindowsXP. I have tried py2exe. The program compiles, but when I execute it nothing happens. I am using Python 2.3.3, and py2exe 0.5.3.

I compile it like this, from the command prompt:

X:\Gen3\Python>c:\Python23\python.exe setup.py py2exe


Here is the output:


running py2exe
*** searching for required modules ***
*** parsing results ***
creating python loader for extension 'datetime'
creating python loader for extension 'numarray._bytes'
.
.
.
creating python loader for extension 'numarray._ufuncFloat64'
*** finding dlls needed ***
*** create binaries ***
*** byte compile python files ***
byte-compiling X:\Gen3\Python\build\bdist.win32\winexe\temp\_sre.py to _sre.pyc
.
.
.
skipping byte-compilation of c:\Python23\lib\StringIO.py to StringIO.pyc
.
.
.
*** copy extensions ***
*** copy dlls ***
setting sys.winver for 'X:\Gen3\Python\dist\python23.dll' to 'py2exe'
copying c:\Python23\lib\site-packages\py2exe\run_w.exe -> X:\Gen3\Python\dist\pr
oblem.exe


Here is a test program, along with my simple config file. What am I doing wrong?

Disclaimer: I am electrical engineer, only able to hack my way through code. Not understand OO too good.

Code:
from Tkinter import *
WINDOW = 600
root = Tk()
root.title('HELP ME!')
canvas = Canvas(root, width=WINDOW, height=WINDOW, background='white')
canvas.create_text(.5*WINDOW,WINDOW-.1*WINDOW,text="",font=("Helvetica", 12),tags="text_tag",fill="#00b000")
canvas.itemconfigure("text_tag",text="Why won't this work?")
canvas.pack()


Code:
from distutils.core import setup
import py2exe
setup( windows=["problem.py"])

Reply With Quote
  #2  
Old July 28th, 2004, 10:10 AM
Grim Archon's Avatar
Grim Archon Grim Archon is offline
Mini me.
Dev Shed Novice (500 - 999 posts)
 
Join Date: Nov 2003
Location: Cambridge, UK
Posts: 783 Grim Archon User rank is Corporal (100 - 500 Reputation Level)Grim Archon User rank is Corporal (100 - 500 Reputation Level)Grim Archon User rank is Corporal (100 - 500 Reputation Level)Grim Archon User rank is Corporal (100 - 500 Reputation Level)  Folding Points: 1488 Folding Title: Novice Folder
Time spent in forums: 3 Days 2 h 15 m 57 sec
Reputation Power: 7
Send a message via MSN to Grim Archon
As a general rule don't try packaging python code with py2exe until you are sure it runs the traditional way. (either from the command line "c:\python23\python myprog.py" or with idle with the F5 key)

Your sample requires the following as it's final line for Tkinter to actaully get started:

Code:
root.mainloop()


when the application runs then look at some of the examples in the forum (keyword "py2exe").

Also - makes sure you are running py2exe 0.5.

I too was and an E/E Engineer once, then I found software

grm
__________________
*** Experimental Python Markup CGI V2 ***

Reply With Quote
  #3  
Old July 28th, 2004, 11:03 AM
elesys elesys is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jul 2004
Location: Atlanta
Posts: 5 elesys User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
Send a message via Yahoo to elesys
Excellent!

Wow, thanks for the quick response and not flaming me for such a lame question! It works! I simply added root.mainloop() at the end.


I do have one thing that puzzles me: the code I originally posted I had checked out using IDLE and it did display a window. Therefore, I thought the code was okay. Obviously, I am used to writing things in a linear fashion and this is one of those OO things (the mainloop thing). If you guys will humor me for just a second, I'd like to post my original piece of software (that indeed works under IDLE) and ask your help in cleaning it up and making it elegant. It works, but has no mainloop() call. It interfaces through the serial port to a little AVR microcontroller and displays the data it reads. It takes 10 samples, writes the data into a CSV file, and exits.

Thanks in advance for your help!

Code:
#************************************************************************
# $Author: ehawkins $
# $Date: 2004/07/09 17:32:39 $
#
# $Log: gen3.py,v $
# Revision 1.1  2004/07/09 17:32:39  ehawkins
# Initial check-in of Python monitor code
#
#************************************************************************

from Tkinter import *
import pickle
import time
import re
import serial
import numarray
import csv

WINDOW = 600
NSAMPLES = 254
MAX = 1040
CHANNELS = 2
FRAMINGBYTES = 4


def OpenSerial():
    global ser
    ser = serial.Serial()
    if ser.isOpen():
        ser.close()
    ser.baudrate = 9600
    ser.port = 'COM1'
    ser.open()
    ser.setDTR()

def CloseSerial():
    try:
        if ser.isOpen():
            ser.close()
    except:
        print "WARNING: Exception raised: ser.close() attempted before ser defined"
    else:
        print "WARNING: ser.close() has issues"

root = Tk()
root.title('GEN3')
root.bind('q','exit')
canvas = Canvas(root, width=WINDOW, height=WINDOW, background='white')
canvas.create_text(.1*WINDOW,WINDOW-.02*WINDOW,text="",font=("Helvetica", 12),tags="v00",fill="#00b000")
canvas.create_text(.1*WINDOW,WINDOW-.1*WINDOW,text="",font=("Helvetica", 12),tags="v10",fill="#b00000")

canvas.create_text(.30*WINDOW,WINDOW-.02*WINDOW,text="",font=("Helvetica", 12),tags="v0n",fill="#00b000")
canvas.create_text(.30*WINDOW,WINDOW-.1*WINDOW,text="",font=("Helvetica", 12),tags="v1n",fill="#b00000")

canvas.create_text(.50*WINDOW,WINDOW-.02*WINDOW,text="",font=("Helvetica", 12),tags="v0-",fill="#00b000")
canvas.create_text(.50*WINDOW,WINDOW-.1*WINDOW,text="",font=("Helvetica", 12),tags="v1-",fill="#b00000")

canvas.create_text(.65*WINDOW,WINDOW-.02*WINDOW,text="",font=("Helvetica", 12),tags="v0c",fill="#00b000")
canvas.create_text(.65*WINDOW,WINDOW-.1*WINDOW,text="",font=("Helvetica", 12),tags="v1c",fill="#b00000")

OpenSerial()

for test in range(10):
    line2d = []
    path = numarray.zeros((CHANNELS, (NSAMPLES*2 + 2)))
    imp = numarray.zeros((CHANNELS, NSAMPLES))
    diff = numarray.zeros((CHANNELS, NSAMPLES))
    byte = numarray.zeros((FRAMINGBYTES))
    cap = numarray.zeros((CHANNELS))
    print "Finding framing ..."
    while not (((byte[0] == 69) & (byte[1] == 114) & (byte[2] == 105) & (byte[3] == 99))|((byte[0] == 78) & (byte[1] == 101) & (byte[2] == 97) & (byte[3] == 116))):
    #while not ((byte[0] == 69) & (byte[1] == 114) & (byte[2] == 105) & (byte[3] == 99)):
       for i in range(FRAMINGBYTES-1):
           byte[i] = byte[i+1]
       byte[FRAMINGBYTES-1] = ord(ser.read())
    if byte[0] == 69:
       channel = 1
       color = "#b00000"
    else:
       channel = 0
       color = "#00b000"

    print byte

    print "Getting channel " + str(channel) + " data ..."
    for datacnt in range(NSAMPLES):
       x = datacnt * 2
       y = x + 1
       lo = ord(ser.read())
       hi = ord(ser.read())
       value = (hi << 8) + lo
       imp[channel][datacnt] = (value)
       path[channel][x] = (WINDOW-(value*WINDOW/float(MAX)))
       path[channel][y] = (WINDOW-(datacnt*WINDOW/float(NSAMPLES)))
       if not (datacnt == 0): diff[channel][datacnt] = imp[channel][datacnt - 1] - value
       if diff[channel][datacnt] < 0: diff[channel][datacnt] = 0

    print imp[channel]
    print value

    for i in range(NSAMPLES*2+2):
        line2d.insert(0,path[channel][i])

    canvas.delete("path"+str(channel))
    canvas.create_line(line2d,tag="path"+str(channel),fill=color)
    canvas.itemconfigure("v"+str(channel)+"0",text="CH[%i][0]: %d"% (channel, imp[channel][-1]))
    canvas.itemconfigure("v"+str(channel)+"-",text="dV/dt: %d"%(imp[channel][NSAMPLES-2]-imp[channel][NSAMPLES-1]))
    canvas.itemconfigure("v"+str(channel)+"n",text="CH[%i][-1]: %d"% (channel, imp[channel][0]))
    canvas.itemconfigure("v"+str(channel)+"c",text="C: %d"% (cap[channel]))
    canvas.itemconfigure("v"+str(channel)+"c",text="C: %d"% ((imp[channel][0]-imp[channel][-1])/(imp[channel][NSAMPLES-2]-imp[channel][NSAMPLES-1])))
    canvas.pack()

    print "CH: %d, %d, c: %d"% (channel, NSAMPLES-2, imp[channel][NSAMPLES-2])
    print "CH: %d, %d, c: %d"% (channel, NSAMPLES-1, imp[channel][NSAMPLES-1])
    
    print "Writing channel " + str(channel) + " data ..."

    grep = re.compile(' |:')
    fNAME = grep.sub("_", str(time.ctime())) + "_CH" + str(channel) + ".csv"
    FILE = open(fNAME, "w")
    FILE.write("Initial Voltage, Final Voltage, dV/dt, Cap\n")
    for i in range(NSAMPLES):
        FILE.write("%u, %u, %u, %u\n" % (line2d[i*2], imp[channel][NSAMPLES-i-1], diff[channel][NSAMPLES-i-1],(imp[channel][0]-imp[channel][-1])/(imp[channel][NSAMPLES-2]-imp[channel][NSAMPLES-1])))
    FILE.close()
CloseSerial()

Reply With Quote
  #4  
Old July 28th, 2004, 04:48 PM
DevCoach DevCoach is offline
Contributing User
Dev Shed Beginner (1000 - 1499 posts)
 
Join Date: Feb 2004
Location: London, England
Posts: 1,203 DevCoach User rank is Captain (20000 - 30000 Reputation Level)DevCoach User rank is Captain (20000 - 30000 Reputation Level)DevCoach User rank is Captain (20000 - 30000 Reputation Level)DevCoach User rank is Captain (20000 - 30000 Reputation Level)DevCoach User rank is Captain (20000 - 30000 Reputation Level)DevCoach User rank is Captain (20000 - 30000 Reputation Level)DevCoach User rank is Captain (20000 - 30000 Reputation Level)DevCoach User rank is Captain (20000 - 30000 Reputation Level)DevCoach User rank is Captain (20000 - 30000 Reputation Level) 
Time spent in forums: 1 Week 5 Days 17 h 10 m 35 sec
Reputation Power: 262
The mainloop() call contains the code that receives the windows events and sends them to the correct controls. The reason your program works in Idle is that Idle is also a TkInter application, so mainloop is already running and your application is piggybacking on top of it.

I don't have the time for in-depth review of your code, but here are some thoughts from aquick scan through...

1) When I see repeated blocks of code I immediately think "use a loop". Replace

Code:
canvas = Canvas(root, width=WINDOW, height=WINDOW, background='white')
canvas.create_text(.1*WINDOW,WINDOW-.02*WINDOW,text="",font=("Helvetica", 12),tags="v00",fill="#00b000")
canvas.create_text(.1*WINDOW,WINDOW-.1*WINDOW,text="",font=("Helvetica", 12),tags="v10",fill="#b00000")

canvas.create_text(.30*WINDOW,WINDOW-.02*WINDOW,text="",font=("Helvetica", 12),tags="v0n",fill="#00b000")
canvas.create_text(.30*WINDOW,WINDOW-.1*WINDOW,text="",font=("Helvetica", 12),tags="v1n",fill="#b00000")

canvas.create_text(.50*WINDOW,WINDOW-.02*WINDOW,text="",font=("Helvetica", 12),tags="v0-",fill="#00b000")
canvas.create_text(.50*WINDOW,WINDOW-.1*WINDOW,text="",font=("Helvetica", 12),tags="v1-",fill="#b00000")

canvas.create_text(.65*WINDOW,WINDOW-.02*WINDOW,text="",font=("Helvetica", 12),tags="v0c",fill="#00b000")
canvas.create_text(.65*WINDOW,WINDOW-.1*WINDOW,text="",font=("Helvetica", 12),tags="v1c",fill="#b00000")

with something like this:

Code:
canvas = Canvas(root, width=WINDOW, height=WINDOW, background='white')
for x in (.1, .30, .50, .65):
  for y in (.02, .1):
    canvas.create_text(x*WINDOW,WINDOW-y*WINDOW,text="",font=("Helvetica", 12),tags="v00",fill="#00b000")


2) Numarray supports comparision of array objects so you could replace

Code:
    while not (((byte[0] == 69) & (byte[1] == 114) & (byte[2] == 105) & (byte[3] == 99))|((byte[0] == 78) & (byte[1] == 101) & (byte[2] == 97) & (byte[3] == 116))):


with

Code:
end1 = numarray.array([69, 114, 105, 99, ])
end2 = numarray.array([78,101, 97, 116])

    while byte != end1 and byte != end2:
       ...

#or even more pythonically:

    while byte not in (end1, end2):
       ...

This will be more efficient, since the comparisions will be done in a single C function call, rather than several Python bytecodes. IMHO it is also much more readable.

Dave - The Developers' Coach

Reply With Quote
  #5  
Old July 28th, 2004, 09:09 PM
elesys elesys is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jul 2004
Location: Atlanta
Posts: 5 elesys User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
Send a message via Yahoo to elesys
Fantastic! Now, just one more question ...

I have noticed that my py2exe compiled code is much SLOWER than its py equivalent. Any suggestion as to why? My first guess is something to do with serial IO and Windows XP?? My second guess would simply be my poor coding style.

By slower I mean the window update via canvas has a slow refresh rate and when I try to grab the window and drag it there is a very perceptible time lag (almost as if the window is frozen).

At any rate, thanks for all your support. It is now 10PM EST US and I have been at work since 7AM. I never imagined I would get so much excellent support over course of single day.

Reply With Quote
  #6  
Old July 29th, 2004, 05:45 AM
Grim Archon's Avatar
Grim Archon Grim Archon is offline
Mini me.
Dev Shed Novice (500 - 999 posts)
 
Join Date: Nov 2003
Location: Cambridge, UK
Posts: 783 Grim Archon User rank is Corporal (100 - 500 Reputation Level)Grim Archon User rank is Corporal (100 - 500 Reputation Level)Grim Archon User rank is Corporal (100 - 500 Reputation Level)Grim Archon User rank is Corporal (100 - 500 Reputation Level)  Folding Points: 1488 Folding Title: Novice Folder
Time spent in forums: 3 Days 2 h 15 m 57 sec
Reputation Power: 7
Send a message via MSN to Grim Archon
Are there any coding differences between your versions?

Is there any difference between the ruuning it from Idle and running it using the python command line?

Py2exe only puts together the byte code with the normal run time.

All things being equal I can't see why there is a slow down - unless perhaps it is a memory issue. It won't be sharing memory/code with anything else so perhaps the problem is actually a memory paging issue.

grim

Reply With Quote
  #7  
Old July 29th, 2004, 09:44 AM
elesys elesys is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jul 2004
Location: Atlanta
Posts: 5 elesys User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
Send a message via Yahoo to elesys
Quote:
Is there any difference between the running it from Idle and running it using the python command line?


As it turns out, there are no differences! I was incorrect to assume py2exe had slowed things down. My recoding to incorporate mainloop() has slowed things down! When I was using a while() loop everything was flowing smoothly. Here is what I have done now, does anyone see any glaring issues? And, can anyone suggest me how to use a CLASS effectively?? I apologize for continuing to post such lengthy code segments, but right now I'm not sharp enough with Python to know how to reduce it to a good testcase.

Code:
from Tkinter import *
import serial
import numarray

WINDOW = 600
NSAMPLES = 254
MAX = 1040
CHANNELS = 2
FRAMINGBYTES = 4


def OpenSerial():
    global ser
    ser = serial.Serial()
    if ser.isOpen():
        ser.close()
    ser.baudrate = 9600
    ser.port = 'COM1'
    ser.open()
    ser.setDTR()

def CloseSerial():
    try:
        if ser.isOpen():
            ser.close()
    except:
        print "WARNING: Exception raised: ser.close() attempted before ser defined"
    else:
        print "WARNING: ser.close() has issues"

def idle(parent, canvas):
    line2d = []
    path = numarray.zeros((CHANNELS, (NSAMPLES*2 + 2)))
    imp = numarray.zeros((CHANNELS, NSAMPLES))
    diff = numarray.zeros((CHANNELS, NSAMPLES))
    byte = numarray.zeros((FRAMINGBYTES))
    cap = numarray.zeros((CHANNELS))
    print "Finding framing ..."
    while not numarray.sometrue(numarray.equal(byte, frame_ch1)| numarray.equal(byte, frame_ch2)):
       for i in range(FRAMINGBYTES-1):
           byte[i] = byte[i+1]
       byte[FRAMINGBYTES-1] = ord(ser.read())
    if byte[0] == 69:
       channel = 1
       color = "#b00000"
    else:
       channel = 0
       color = "#00b000"

    print byte

    print "Getting channel " + str(channel) + " data ..."
    for datacnt in range(NSAMPLES):
       x = datacnt * 2
       y = x + 1
       lo = ord(ser.read())
       hi = ord(ser.read())
       value = (hi << 8) + lo
       imp[channel][datacnt] = (value)
       path[channel][x] = (WINDOW-(value*WINDOW/float(MAX)))
       path[channel][y] = (WINDOW-(datacnt*WINDOW/float(NSAMPLES)))
       if not (datacnt == 0): diff[channel][datacnt] = imp[channel][datacnt - 1] - value
       if diff[channel][datacnt] < 0: diff[channel][datacnt] = 0

    for i in range(NSAMPLES*2+2):
        line2d.insert(0,path[channel][i])

    canvas.delete("path"+str(channel))
    canvas.create_line(line2d,tag="path"+str(channel),fill=color)
    canvas.itemconfigure("v"+str(channel)+"0",text="CH[%i][0]: %d"% (channel, imp[channel][-1]))
    canvas.itemconfigure("v"+str(channel)+"-",text="dV/dt: %d"%(imp[channel][NSAMPLES-2]-imp[channel][NSAMPLES-1]))
    canvas.itemconfigure("v"+str(channel)+"n",text="CH[%i][-1]: %d"% (channel, imp[channel][0]))
    if (imp[channel][NSAMPLES-2] == imp[channel][NSAMPLES-1]):
       canvas.itemconfigure("v"+str(channel)+"c",text="C: INF")
    else:
       canvas.itemconfigure("v"+str(channel)+"c",text="C: %d"% ((imp[channel][0]-imp[channel][-1])/(imp[channel][NSAMPLES-2]-imp[channel][NSAMPLES-1])))
    canvas.pack()
    parent.after_idle(idle, parent, canvas)


if (__name__=="__main__"):

    frame_ch1 = numarray.array([69, 114, 105, 99])
    frame_ch2 = numarray.array([78, 101, 97, 116])
    print "Opening serial port ..."
    OpenSerial()
    root = Tk()
    root.title('GEN3')
    root.bind('q','exit')
    canvas = Canvas(root, width=WINDOW, height=WINDOW, background='white')
    canvas.create_text(.1*WINDOW,WINDOW-.02*WINDOW,text="",font=("Helvetica", 12),tags="v00",fill="#00b000")
    canvas.create_text(.1*WINDOW,WINDOW-.1*WINDOW,text="",font=("Helvetica", 12),tags="v10",fill="#b00000")
    canvas.create_text(.30*WINDOW,WINDOW-.02*WINDOW,text="",font=("Helvetica", 12),tags="v0n",fill="#00b000")
    canvas.create_text(.30*WINDOW,WINDOW-.1*WINDOW,text="",font=("Helvetica", 12),tags="v1n",fill="#b00000")
    canvas.create_text(.50*WINDOW,WINDOW-.02*WINDOW,text="",font=("Helvetica", 12),tags="v0-",fill="#00b000")
    canvas.create_text(.50*WINDOW,WINDOW-.1*WINDOW,text="",font=("Helvetica", 12),tags="v1-",fill="#b00000")
    canvas.create_text(.65*WINDOW,WINDOW-.02*WINDOW,text="",font=("Helvetica", 12),tags="v0c",fill="#00b000")
    canvas.create_text(.65*WINDOW,WINDOW-.1*WINDOW,text="",font=("Helvetica", 12),tags="v1c",fill="#b00000")
    canvas.pack()
    print "Calling main loop ..."
    root.after(100 ,idle, root, canvas)
    root.mainloop()

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesPython Programming > py2win and tkinter not working well together


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump


Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 





© 2003-2008 by Developer Shed. All rights reserved. DS Cluster 2 hosted by Hostway