5 Replies - 349 Views - Last Post: 12 August 2014 - 11:28 AM Rate Topic: -----

#1 Bungo Mungo  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 19
  • Joined: 23-June 14

Turn Program Into Clickable Application

Posted 29 July 2014 - 01:18 PM

Hello,

I have a fraction calculator program that I wrote that has a GUI. I wrote it in Eclipse, but I want to turn it into a application that runs when you click on the icon. I've tried py2exe and cx_freeze, but all that happens when I click on the .exe file is a shell opens for a split second and then closes right away. It doesn't even show my GUI. I might need something in my code that I don't currently have, so I'll post that here:

# Import necessary libraries
from tkinter import *
from tkinter import ttk
from fractions import gcd


# Determines which function to call based on which
# operator the user chose
def calc(*args):
    opChoice = opVar.get()
    

    if opChoice == '*':
        mult()
    elif opChoice == '/':
        div()
    elif opChoice == '+':
        add()
    elif opChoice == '-':
        sub()


# Multiplies two fractions
def mult(*args):
    
    n1 = int(num1.get())
    n2 = int(num2.get())
    d1 = int(den1.get())
    d2 = int(den2.get())
    num = n1*n2
    den = d1*d2
    answ = reduce(num, den)
    answer.set(answ)

# Divides two fractions
def div(*args):
    
    n1 = int(num1.get())
    n2 = int(num2.get())
    d1 = int(den1.get())
    d2 = int(den2.get())
    num = n1*d2
    den = d1*n2
    answ = reduce(num, den)
    answer.set(answ)

# Adds two fractions
def add(*args):
    
    n1 = int(num1.get())
    n2 = int(num2.get())
    d1 = int(den1.get())
    d2 = int(den2.get())
    if d1 == d2:
        answ = reduce(n1+n2, d1)
        answer.set(answ)
    else:
        n1, n2 = n1*d2, n2*d1
        d = d1*d2
        answ = reduce(n1+n2, d)
        answer.set(answ)

# Subtracts two fractions
def sub(*args):
    
    n1 = int(num1.get())
    n2 = int(num2.get())
    d1 = int(den1.get())
    d2 = int(den2.get())
    if d1 == d2:
        answ = reduce(n1-n2, d1)
        answer.set(answ)
    else:
        n1, n2 = n1*d2, n2*d1
        d = d1*d2
        answ = reduce(n1-n2, d)
        answer.set(answ)
        

# Checks to see if the answer is able to be reduced
# If so, it returns the fraction in reduced form
def reduce(num, den):
     
    divisor = gcd(num, den)
    if divisor <= 1:
        return ('%d/%d' % (num, den))
    else:
        return ('%d/%d' % (num/divisor, den/divisor))
        


#-----------------------------GUI Components------------------------------#

# Create root window
root = Tk()
root.title("Fraction Calculator")

# Create a frame that all our widgets will go into
mainframe = ttk.Frame(root, padding=5)
mainframe.grid(row=0, column=0, sticky=(N, S, E, W))
mainframe.rowconfigure(0, weight=1)
mainframe.columnconfigure(0, weight=1)

# Create all necessary StringVars
num1 = StringVar()
den1 = StringVar()
num2 = StringVar()
den2 = StringVar()
opVar = StringVar()
answer = StringVar()

# Create and display Entry, Combobox, and Label widgets

# Numerator 1
n1_entry = ttk.Entry(mainframe, width=5, textvariable=num1)
n1_entry.grid(row=0, column=0, sticky=(S, E))
# Denominator 1
d1_entry = ttk.Entry(mainframe, width=5, textvariable=den1)
d1_entry.grid(row=1, column=0, sticky=(N, E))
# Numerator 2
n2_entry = ttk.Entry(mainframe, width=5, textvariable=num2)
n2_entry.grid(row=0, column=2, sticky=(S, W))
# Denominator 2
d2_entry = ttk.Entry(mainframe, width=5, textvariable=den2)
d2_entry.grid(row=1, column=2, sticky=(N, W))
# Operation drop down box
op = ttk.Combobox(mainframe, width=5, values=('*', '/', '+', '-'), textvariable=opVar)
op.grid(row=1, column=1, sticky=N)

# Labels to display answer
ttk.Label(mainframe, text="Answer: ").grid(row=2, column=0, sticky=E)
ttk.Label(mainframe, relief=SUNKEN, width=10, textvariable=answer).grid(row=2, column=1, sticky=W)

# Calculate button, performs specified operation when clicked
calcBut = ttk.Button(mainframe, text="Calculate", command = calc).grid(row=2, column=2, sticky=(E, W))


# Adds some extra padding around each widget
for child in mainframe.winfo_children():
    child.grid_configure(padx=5, pady=5)


# Cursor will start in the n1_entry box
n1_entry.focus()

# Specified operation will be executed when Enter key is pressed
root.bind('<Return>', calc)
mainloop()



If you have any ideas on how to do what I'm asking, I'd love to hear them. Also, if you have suggestions on how to make my code better I'd appreciate that feedback as well. Thanks!

Is This A Good Question/Topic? 0
  • +

Replies To: Turn Program Into Clickable Application

#2 andrewsw  Icon User is online

  • Fire giant boob nipple gun!
  • member icon

Reputation: 3480
  • View blog
  • Posts: 11,874
  • Joined: 12-December 12

Re: Turn Program Into Clickable Application

Posted 29 July 2014 - 01:31 PM

I think it should be:
root.mainloop()

(the last line) to keep the window open.

I'm slightly surprised that it doesn't give an error currently, but perhaps mainloop() runs on the default instance of Tk(), not the one you've created. (I'm just guessing ;))
Was This Post Helpful? 0
  • +
  • -

#3 Bungo Mungo  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 19
  • Joined: 23-June 14

Re: Turn Program Into Clickable Application

Posted 30 July 2014 - 09:21 AM

View Postandrewsw, on 29 July 2014 - 01:31 PM, said:

I think it should be:
root.mainloop()


I just changed it and tried to convert it to a .exe using cx_freeze and it still does the same thing. The program works perfectly in Eclipse with or without the root.mainloop() (although it should definitely have the "root." thanks for pointing that out). I would like for the GUI to show up when you click on the .exe file, but the shell just opens for half a second and closes and that's all that happens. Is it simple to accomplish this or is there a more complex method involved?
Was This Post Helpful? 0
  • +
  • -

#4 andrewsw  Icon User is online

  • Fire giant boob nipple gun!
  • member icon

Reputation: 3480
  • View blog
  • Posts: 11,874
  • Joined: 12-December 12

Re: Turn Program Into Clickable Application

Posted 30 July 2014 - 09:30 AM

Dunno, never used it ;)

This build script supposedly hides the console (from here):
import sys
from cx_Freeze import setup, Executable

base = None
if (sys.platform == "win32"):
    base = "Win32GUI"    # Tells the build script to hide the console.

# <The rest of your build script goes here.>

But if the console displays then I'll guess that it is because there are errors. I would attempt to produce an input() prompt to delay the closing of the console, so that at least I could read the error message.

Perhaps someone else will contribute ;)
Was This Post Helpful? 1
  • +
  • -

#5 jmoore  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 08-August 14

Re: Turn Program Into Clickable Application

Posted 08 August 2014 - 01:35 PM

Not sure if relevant but you import twice from tkinter, and I thought the first import would do as it uses the asterix to import all?
Was This Post Helpful? 0
  • +
  • -

#6 Bungo Mungo  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 19
  • Joined: 23-June 14

Re: Turn Program Into Clickable Application

Posted 12 August 2014 - 11:28 AM

View Postjmoore, on 08 August 2014 - 01:35 PM, said:

Not sure if relevant but you import twice from tkinter, and I thought the first import would do as it uses the asterix to import all?


That's what I thought too, but if I comment out "from tkinter import ttk" I get a NameError that says ttk is not defined. ttk changes the theme of the widgets so that they look like the default windows, buttons, labels, etc. of your OS. So maybe it's another library within tkinter and you have to import it separately. Anyone know what's actually going on here?
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1