Converting a script into GUI using Tkinter - python

I really need help, I have written a script that implements a flow equation. The problem is that i would love to convert this to a GUI, I am a student and i am meant to submit this assignment anytime soon, i don't have time for learning Tkinter now but i will surely learn it next month. the script below:
print ("this program measures gas flowrate in pipes with effect of elevation, making use of USCS unit")
e=2.718
Tb=520
Pb=14.7
f=float(input("Friction factor,f: "))
P1=float(input("upstream pressure,P1: "))
P2=float(input("downstream pressure,P2: "))
G=float(input("gas gravity,G: "))
Tf=float(input("average gas flowing temperature,Tf: "))
L=float(input("pipe line segment,L: "))
Z=float(input("gas compressibility factor at flowing temperature,Z: "))
D=float(input("pipe inside diameter,D: "))
H1=float(input("upstream elevation,H1: "))
H2=float(input("downstream elevation,H2: "))
s=float((0.0375*G)*((H2-H1)/(Tf*Z)))
j=float((e**s-1)/s)
Le=float(L*j)
F=float(2/f**0.5)
Q=38.77*F*(Tb/Pb)*((P1**2-(e**s*P2**2))/(G*Tf*Le*Z))**0.5*D**2.5
print(j);
print(s);
print(Q);
Thanks alot for assistance

First, import tkinter and create the main object:
import Tkinter as tk
master = tk.Tk()
Then create inputs that will go in the main window. For each input, create a label and an entry for the input:
Example:
L1 = tk.Label(master, text="friction factor, f: ")
L1.pack()
L1.grid(row=0, column=0)
E1 = tk.Entry(master, bd =5)
E1.pack()
E1.grid(row=0, column=1)
# .... all other labels and input entries
# And a label for the result:
result = tk.Label(master)
result.pack()
Then, get all values from the entries to variables, for example:
f = float(E1.get())
Add a button to press for calculation:
button = tk.Button(master, text='Calculate', command=calculate)
button.pack()
# calculate is a function that you will define, that gets all values from the input and returns the final value. Send also the result label to the function to change the text of the result label.
def calculate(result, f, .....):
# Your calculating algorithem
output = "j: " + str(j) + ", Q: "+ str(Q) + ", s: "+str(s)
result.config(text=output)
In the end of your code, you will have this line that runs the window:
master.mainloop()
If you need further explanation, please write.

Related

I am working on my first tkinter project and i need some guidance

Here I've uploaded the entire code. The problem is on entering a non integer in the field, the program halts and it force quits. I tried solving it by using the part of code I've commented out. My solution doesn't work, so any guidance would be helpful.
from tkinter import *
root = Tk()
def sarteg():
**#while True:
# try:
# a= int(e.get())
# except ValueError:
# eror= Label(root,text="Please enter an integer").pack()
# continue
# else:
# break**
a= int(e.get())
if a%2==0:
even=Label(root,text="number is even").pack()
else:
odd=Label(root,text="number is odd").pack()
label1= Label(root, text="Enter an Integer then click on \"FIND OUT\"").pack()
e = Entry(root, width=20)
e.pack()
mybutt= Button(root, text="find out", command=sarteg)
mybutt.pack()
root.mainloop()
I tried the code, it seems to working fine.
You had error on line 5.
You added 2 asterisks.
**#while True:
If you remove the asterisks, it's working fine. Comments can be added by just adding # before the line.
One more thing I'd recommend it to create a common label to show the results. Because every time you check the number a new label appears creating a list of results.
I believe all you really have to do is remove the while True statement. Try this:
def sarteg():
try:
a = int(e.get())
except ValueError:
eror = Label(root, text="Please enter an integer").pack()
return None
if a % 2 == 0:
even = Label(root, text="number is even").pack()
else:
odd = Label(root, text="number is odd").pack()

taking an integer value from an entry widget in tkinter

I wrote some simple code to describe my problem: I want to take an integer value from an entry to use it later.I tried also to use a spin box. here is my code:
from tkinter import*
win=Tk()
win.geometry('300x200')
e=Entry(width=10)
e.pack()
y=int(e.get())
print(y*2)
I always get the same error:
y = int(e.get())
ValueError: invalid literal for int() with base 10 ' '
I don't know why this is happening!
ValueError: invalid literal for int() with base 10 ' '
means that you are trying to convert the string "" to an integer. This, of course, is invalid. The reason you are trying to convert an empty string to an integer is that you are not allowing any value to be placed into the entry.
A good way to allow this to happen would be using a button, which calls a function to get the value within the entry and print it. Also, you are missing the line win.mainloop() which you would need at the end of your code.
Here is the example code you are probably asking for:
from tkinter import *
win = Tk()
win.geometry('300x200')
def printVal():
y = int(e.get())
print(y*2)
e = Entry(width=10)
e.pack()
b = Button(text="push me to print the value in e")
b.pack()
win.mainloop()
This code will still return errors if the value in the entry is not a valid integer, so if you want it to be robust, you'll have to play around with it.
there is several problems in your example, for example. in which moment you are trying to get value from Entry?
your code should looks something like:
from tkinter import *
def validate(value):
print (value)
try:
if value:
return int(value)
except:
return None
def calculate():
x = e1.get()
x_validate = validate(x)
if x_validate == None:
e1.delete(0, END)
e1.insert(0, 'you need to enter integer')
Label1.config(text='')
else:
result = x_validate*2
Label1.config(text=result)
win = Tk()
e1 = Entry(win)
e1.grid(row=0, column=0)
Button(win,text='Calculate', command = calculate).grid(row=0, column=1)
Label(win,text='Result').grid(row=1, column=0)
Label1 = Label(win)
Label1.grid(row=1, column=1)
win.mainloop()
Example if you enter integer and press calculate
Example if you enter string and press calculate

How can I have a Tkinter program scan a text box for inputs in real time?

Ultimately I want to make a small program with a text box where you have to type in the first 50 or so digits of Pi. What I want is for nothing to happen if the user types the correct characters, but I want something to flash red if they input the wrong character. For example, if the user types "3.1", nothing happens but the text showing up in the text box, but if they then type the wrong number, like "3.15", I want something to flash red.
from tkinter import *
def input(event):
inp = (ent.get('1.0', END))
if inp == '3':
print(inp)
else:
print(('--') + (inp))
root = Tk()
root.title('pi, okay')
root.geometry('425x50')
ent = Text(root, width = 50, height = 1)
ent.bind('<KeyRelease>', input)
ent.pack()
mainloop()
What I think SHOULD happen with this is for the console to print "3" IF the user inputs a "3", and for the console to print "--(whatever else the user would have typed)" if it is not a 3. But what actually happens is that the program will print "--(input)" no matter what.
You can use something like this if you need only one line of Input:
var = StringVar()
ent = Entry(root, width=50, textvariable=var)
def check_value(var, ent, *args):
pi = "3.1415"
if not pi.startswith(var.get()):
print("wrong input")
ent.config(fg="red")
else:
ent.config(fg="black")
var.trace('w', lambda *args: check_value(var, ent, *args))
ent.pack()
Here, var.trace() will call function check_value everytime when user types anything in Entry widget. You can add you logic there to verify the input value and change UI(or print logs) based on verification result.

Separate Buttons to track separate values [python]

I am building a rudimentary python program for tracking bullet fire in my local Rogue Trader campaign. I hate writing - erasing - rewriting on my sheet leaving it smudged and gross. This gives me an excuse to practice my coding skills. Eventually going to have it save values to a file and then read them upon start up, but that's in the future.
I am letting it ask for what guns I have, setting a clipSize for said gun, and then create a button that references each gun. Upon pressing the button, fireGun is supposed to take the value of the gun shot corresponding to which button is pressed. However, the way it runs currently, all guns fire from the same ammo amount which is the last 'clipSize' entered.
I need each button to track its own variable to update the correct dictionary reference upon fireGun.
from tkinter import *
addGuns = 'true'
gunList = {}
while (addGuns == 'true'):
newGun = input("What is the name of your gun? ")
clipSize = int(input("What is its clip size? "))
gunList[newGun] = clipSize
gunCheck = input("Done adding guns? ")
if (gunCheck == 'yes'):
addGuns = 'false'
root = Tk()
root.title("Pew Pew")
def fireGun(x):
startingAmmo = gunList[x]
endingAmmo = startingAmmo - 1
gunList[x] = endingAmmo
print(gunList[x])
return
for gun in gunList:
button = Button(root, text = gun, command = lambda name = gun:fireGun(gun))
button.pack()
root.mainloop()
Use partial to send parameters to a function with a command= call. You could also use an Entry to get the gun info, and one label for each gun with the name and updated ammo amount on each label. A very sloppy example (I have to go to work).
from tkinter import *
from functools import partial
gunCheck="no"
gunList = {}
while gunCheck != 'yes':
newGun = input("What is the name of your gun? ")
clipSize = int(input("What is its clip size? "))
gunList[newGun] = int(clipSize)
gunCheck = input("----->Done adding guns? ")
## if (gunCheck == 'yes'):
## addGuns = 'false'
root = Tk()
root.title("Pew Pew")
def fireGun(x):
startingAmmo = gunList[x]
endingAmmo = startingAmmo - 1
gunList[x] = endingAmmo
print(gunList[x])
label_list[x].config(text=x + "-->" + str(endingAmmo))
return
label_list={}
fr=Frame(root)
fr.pack(side="top")
for gun in gunList:
lab=Label(fr, text="%s --> %d" %(gun, gunList[gun]))
lab.pack(side=TOP)
label_list[gun]=lab
button = Button(root, text = gun, command = partial(fireGun, gun))
button.pack()
root.mainloop()

How to use .get() within a function. Python

from Tkinter import *
import random
def Factorer(a,b,c):
while True:
random_a1=random.randint(-10,10)
random_a2=random.randint(-10,10)
random_c1=random.randint(-10,10)
random_c2=random.randint(-10,10)
if random_a1==0 or random_a2 == 0 or random_c1 == 0 or random_c2 == 0:
pass
elif (random_a1*random_c2) + (random_a2*random_c1) == b and random_a1/random_c1 != random_a2/random_c2 and random_a1*random_a2==a and random_c1*random_c2==c:
break
print "y=(%dx+(%d))(%dx+(%d))" % (random_a1,random_c1,random_a2,random_c2)
root = Tk()
buttonSim1 = Button(root, text="Convert", command=lambda: Factorer(enterA.get(),enterB.get(),enterC.get()))
buttonSim1.grid(row=2, column=3)
enterA = Entry(root)
enterA.grid(row=1, column=1)
enterB = Entry(root)
enterB.grid(row=1, column=2)
enterC = Entry(root)
enterC.grid(row=1, column=3)
root.mainloop()
How can I get this code to run, every time I click the button It just crashes.
It works however if I remove the .get() and just insert numbers.
Thanks in advance
You are comparing strings to ints, you would need to cast a,b and c to int:
Tkinter.Button(root, text="Convert", command=lambda: Factorer(int(enterA.get()),int(enterB.get()),int(enterC.get())))
The root of the problem is that you're comparing strings to integers, so your infinite while loop never finishes. That is why the program hands and has to be force-quit.
The best solution is to have your button call a function that gets the data, formats it to the proper value, and then calls the function to do the work. Trying to squeeze all of that into a lambda makes for a program that is hard to debug.
For example:
def on_button_click():
a = int(enterA.get())
b = int(enterB.get())
c = int(enterC.get())
result = Factorer(a,b,c)
print(result)
Tkinter.Button(..., command=on_button_click)
By using a separate function, it gives you the opportunity to add print statements or pdb breakpoints so you can examine the data as it is running. It also makes it easier to add try/catch blocks to handle the case where the user didn't enter valid numbers.

Categories

Resources