I need a to send data to script with submit button - python

I'm building a python GUI and there I got 2 text boxes.
I want to create a submit button that will take the data from those 2 text boxes and send them to start(save_place, website_url) function.
This is what I got so far:
from Tkinter import *
def start(save_place, website_url):
#something
app = Tk()
top_app = Frame(app)
top_app.pack()
save_location = Entry(top_app, width=20)
url = Entry(top_app, width=20)
save_location.grid(sticky=W, row=0)
url.grid(sticky=W, row=1)
save_place = save_location.get("1.0", END)
website_url = url.get("1.0", END)
button_start = Button(top_app, text="Start", fg="green", command=start(save_place,website_url))
button_start.grid(sticky=W, row=2, pady=20)
app.mainloop()
I also tried this:
from Tkinter import *
def start():
save_place = save_loc.get()
website_url = urls.get()
print (save_place + " " + website_url)
app = Tk()
top_app = Frame(app)
top_app.pack()
save_loc = StringVar()
save_location = Entry(top_app, textvariable=save_loc, width=85)
urls = StringVar()
url = Entry(top_app, textvariable=urls, width=85)
button_start = Button(top_app, text="Start", fg="green", command=start)
button_start.grid(sticky=W, row=2, pady=20)
app.mainloop()
And it didn't work.
How can I make this script send the inputs in the text boxes to the function?
Thanks to all the helpers :)

As mentioned in the previous response "about how to call a function", you just put command = start and put save_place = save_location.get()
in start function, however you can use save_location = Entry(top_app, width=20), so the total prg:
from Tkinter import *
def start():
#something
save_place = save_location.get()
website_url = url.get()
print save_place,website_url
app = Tk()
top_app = Frame(app)
top_app.pack()
save_location = Entry(top_app, width=20)
url = Entry(top_app, width=20)
save_location.grid(sticky=W, row=0)
url.grid(sticky=W, row=1)
button_start = Button(top_app, text="Start", fg="green", command=start)
button_start.grid(sticky=W, row=2, pady=20)
app.mainloop()

command=start(save_place,website_url) doesn't do what you think its doing. It's assigning the result of the function call to the command. (Which is probably None). Bind your Entry boxes to StringVar like:
location = StringVar()
Entry(top_app, textvariable=location, width=20)
Then you assign the function call to the command parameter using command = start. Inside the function you can access the value in the Entry using location.get(). To set the value use the corresponding method location.set(value)

Related

How can I return a variable from a function that is opening a file using filedialog after selecting a tkinter button?

All of the tutorials I have seen deomonstrate the tkinter filedialog.askopenfilename function by only using the information collected within the function that is linked to the tkinter button. I can pass information in the function, but I would like to pass variables (filepath, images, etc.) outside the function and have them update variables in my GUI.
I have commented out the location I would like to call the variables in main_gui_setup function below. Any help will be appreciated, as it has been very demoralizing not being able to open a file. If this problem persists, my future as a programmer may be limited to creating tic-tac-toe games or instructional videos for Youtube.
from tkinter import *
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog, messagebox
from PIL import ImageTk, Image # was import PIL.Image, PIL.ImageTk
import cv2
def main():
root = Tk()
window1 = Window(root, "X-ray Assist", "Give up")
return None
# can't pass by reference in python
class Window():
n = 0
file_path = ""
img1_info = ""
def __init__(self, root, title, message):
self.root = root
self.root.title(title)
#self.root.geometry(geometry)
self.screen_width = root.winfo_screenwidth()
self.screen_height = root.winfo_screenheight()
#self.root.attributes('-topmost', 1)
# SET APP WINDOW SIZE
scr_size_main = self.scr_size() # create instance of scr_size
self.root.geometry("%dx%d+%d+%d" % (self.root_width, self.root_height, self.root_x, self.root_y))
# CREATE MAIN WINDOW GUI
create_gui = self.main_gui_setup()
self.root.mainloop()
pass
def scr_size(self):
'''Reads monitor size and adjusts GUI frame sizes'''
self.root_width = int(self.screen_width*0.52)
self.root_height = int(self.screen_height*0.9)
self.root_x = int(self.screen_width*0.23)
self.root_y = int(self.screen_height*0.02)
self.img_ht_full = int(self.screen_height*0.82)
self.tools_nb_width = int(self.screen_width*0.22)
self.tools_nb_height = int(self.screen_height*0.48)
self.hist_nb_width = int(self.screen_width*0.22)
self.hist_nb_height = int(self.screen_height*0.23)
def open_image(self):
main_win = ttk.Frame(self.root)
main_win.grid(column=0, row=0)
self.file_path = filedialog.askopenfilename(initialdir='/', title='Open File',
filetypes=(('tif files', '*.tif'), ('all files', '*.*')))
self.file_path_label = ttk.Label(main_win, text=self.file_path)
self.file_path_label.grid(column=0, row=0, columnspan=1, sticky="nw", padx=(5,0), pady=1)
self.img1_8bit = cv2.imread(self.file_path, 0) #, cv2.IMREAD_ANYDEPTH | cv2.IMREAD_GRAYSCALE)
#self.img1_8bit_resize = cv2.resize(self.img1_8bit, (self.img_ht_full, self.img_ht_full)) #, interpolation = cv2.INTER_CUBIC)
#self.img1_height, self.img1_width = self.img1_8bit.shape # not resized for screen
#img1_info = text = f"{self.img1_height} {self.img1_8bit.dtype} {self.img1_16bit.dtype}"
#print(self.img1_width, " x ", self.img1_height, " bitdepth = ", self.img1_8bit.dtype)
#img1_info = ttk.Label
#print(f"{self.img1_height} {self.img1_width} {self.img1_8bit.dtype}")
#img1_info.grid(column=3, row=1, columnspan=1, sticky="w", padx=(5,0), pady=1)
#img = io.imread(main_win.filename) #scikit
self.img1_16bit = cv2.imread(self.file_path, cv2.IMREAD_ANYDEPTH | cv2.IMREAD_GRAYSCALE)
#self.img_canvas = tk.Canvas(self.root, width=self.img_ht_full, height=self.img_ht_full)
#self.img_canvas.grid(column=1, row=2, columnspan=10, rowspan=10, sticky="nw")
#self.img_canvas.image = ImageTk.PhotoImage(image=Image.fromarray(self.img1_8bit_resize))
#self.img_canvas.create_image(0,0, image=self.img_canvas.image, anchor="nw")
# .create_line(x1, y1, x2, y2, fill="color")
#self.img_canvas.create_line((self.img_ht_full/2), 0, (self.img_ht_full/2), (self.img_ht_full), fill="yellow")
#self.img_canvas.create_line(0, (self.img_ht_full/2), (self.img_ht_full), (self.img_ht_full/2), fill="yellow")
def main_gui_setup(self):
main_win = ttk.Frame(self.root)
main_win.grid(column=0, row=0)
image_win = ttk.Frame(main_win, borderwidth=25, relief="groove", width=self.img_ht_full, height=self.img_ht_full)
image_win.grid(column=1, row=2, columnspan=10, rowspan=10, sticky="nw")
toolbar = ttk.Frame(main_win, borderwidth=5) #, width=1100, height=15)
toolbar.grid(column=0, row=0, columnspan=10, rowspan=1, sticky="nw", padx=20)
hist_win = ttk.Frame(main_win, borderwidth=25, relief="groove", width=300, height=200)
panel_info = ttk.Label(main_win, text=f"{self.screen_width} x {self.screen_height}")
panel_info.grid(column=5, row=1, columnspan=1, sticky="e", pady=1)
# SCROLL SLIDER AT BOTTOM
slider = ttk.Scrollbar(main_win, orient="horizontal")
slider.grid(column=1, row=13, columnspan=7, padx=5, pady=5, sticky="ew")
#X-RAY AND DETECTOR SETTINGS - will input these from separate class
kv = ttk.Label(main_win, text="125kV")
kv.grid(column=0, row=2, columnspan=1, padx=15, pady=5)
file_path_label = ttk.Label(main_win, text="No image loaded")
file_path_label.grid(column=1, row=1, columnspan=1, sticky="nw", padx=(5,0), pady=1)
# CREATE BUTTONS
open = ttk.Button(toolbar, text="Open", width=10, command=self.open_image)
open.grid(column=0, row=0)
save = ttk.Button(toolbar, text="Save", width=10)
save.grid(column=1, row=0)
b1 = ttk.Button(toolbar, text="1", width=10)
b1.grid(column=2, row=0)
b2 = ttk.Button(toolbar, text="2", width=10)
b2.grid(column=3, row=0)
pass
main()
You aren't thinking of event driven programming correctly. In event driven programming you have callbacks to the functions you defined. Let's look at your code:
def get_path(self):
...
self.path_label = ...
...
def main_gui_setup(self):
main_win = ttk.Frame(self.root)
main_win.pack()
open = ttk.Button(main_win, text="Open", width=10, command=self.get_path)
open.pack()
# Problematic code:
# main_label = ttk.Label(main_win, self.path_label)
# main_label.pack()
When main_gui_setup is called it creates a frame and a button inside it. When the button is clicked it calls get_path which sets up the path_label variable. The problem that you were facing is that that as soon as you create your button (without waiting for the button to be pressed), you create the label called main_label.
For a simple fix to your problem try this:
def get_path(self):
...
self.file_path = ...
self.path_label = ...
...
def button_callback(self, main_win):
# set up
self.get_path()
# My guess is that you wanted `self.file_path` here instead of `self.path_label`
main_label = ttk.Label(main_win, self.file_path)
main_label.pack()
def main_gui_setup(self):
main_win = ttk.Frame(self.root)
main_win.pack()
# I am using a lambda and passing in `main_win` because you haven't
# assigned it to `self` using `self.main_win = ...`
open = ttk.Button(main_win, text="Open", width=10, command=lambda: self.button_callback(main_win))
open.pack()
I am still confused by what You are trying to accomplish:
from tkinter import Tk, Button, Label, filedialog
class MainWindow(Tk):
def __init__(self):
Tk.__init__(self)
self.open_file_btn = Button(self, text='Open', command=self.open_file)
self.open_file_btn.pack()
self.file_name = None
def open_file(self):
self.file_name = filedialog.askopenfilename()
Label(self, text=self.file_name).pack()
root = MainWindow()
root.mainloop()
I will explain what will happen here! (You can change the .askopenfilename() attributes obviously).
When the program opens the filedialog and You select a file, that file name will now get assigned to self.file_name and that variable can be used anywhere in the class.
also from what I have seen You should learn more about classes and PEP 8

Tkinter button - Replacing old info with new when pressed

Need help solving this problem, I'm a beginner going crazy over this. Each time I press "pingButton1" I want the "pingResult1" to refresh the information insteed of adding new every time I press it. It's a simple "check if ping is good" program.
Any suggestions?
stacking
I've tried using google but nothing is working for me.
from tkinter import *
import os
import subprocess
from time import sleep
menu = Tk()
menu.title("Panel")
menu.geometry("250x380+700+500")
menu.resizable(0, 0)
menu.configure(background="#0d335d")
def close():
screen.destroy()
def pingWindow1():
global ip1
global pingButton1
global screen
screen = Toplevel(menu)
screen.title("Ping Windows")
screen.geometry("300x250+650+300")
screen.configure(background="#0d335d")
blank = Label(screen, bg="#0d335d", text="")
blank.pack()
ip1 = Entry(screen, width=20, bg="white")
ip1.pack()
blank1 = Label(screen, bg="#0d335d", text="")
blank1.pack()
pingButton1 = Button(screen, text="Ping away..", width="20", bg="#e5e5e5", height="2", borderwidth=2, relief="ridge", command=pingResult1)
pingButton1.pack()
close_ping = Button(screen, text="Close", width="20", bg="#e5e5e5", height="2", borderwidth=2, relief="ridge", command=close)
close_ping.pack()
blank2 = Label(screen, text="", bg="#0d335d")
blank2.pack()
screen.bind('<Escape>', lambda _: close())
def pingResult1():
global pingIP1
pingIP1 = ip1.get()
try:
overall_mgm()
except:
return False
try:
overall_mgm_RO()
except:
return False
done = Label(screen, text="Completed").pack()
def overall_mgm():
response = os.system("ping -c 1 sekiiws00"+pingIP1)
if response is not 0:
fail = Label(screen, bg="black", fg="red", text="KI FAILED").pack()
else:
success = Label(screen, bg="black", fg="green", text="KI SUCCESS").pack()
def overall_mgm_RO():
response = os.system("ping -c 1 seroiws00"+pingIP1)
if response is not 0:
fail = Label(screen, bg="black", fg="red", text="RO FAILED").pack()
else:
success = Label(screen, bg="black", fg="green", text="RO SUCCESS").pack()
# Widget
option = Button(menu, text="Ping IP", width="20", bg="#e5e5e5",height="2", borderwidth=2, relief="ridge", command=pingWindow1)
# Out
option.pack()
menu.mainloop()
I'm guessing I need something like this
if pingButton1 clicked more than once
refresh current Labels( fail & success)
def pingResult1():
global pingIP1
pingIP1 = ip1.get()
try:
overall_mgm()
except:
return False
try:
overall_mgm_RO()
except:
return False
done = Label(screen, text="Completed").pack()
with this demo you can change button's text (for example) when pressed.
import tkinter
from functools import partial
# partial is good for passing `function` and `its args`
def button_command(button):
# for example
button.config(text="another value")
# creating new button
# root is whatever you want
button = tkinter.Button(root, text="something")
# add command to button and passing `self`
button.config(command=partial(button_command, button))
button.pack()
adapt this example to your code and you are good to go.

get entered text and exit if the text in mass (tkinter)

good day! here's my code:
import tkinter as tk
namemass =["dev", "Dev1"]
self.entry_name = ttk.Entry(self)
self.entry_name.place(x=200, y=50)
btn_cancel = ttk.Button(self, text="cancel", command=self.destroy)
btn_cancel.place(x=300, y=800)
btn_ok = ttk.Button(self, text="ok")
btn_ok.place(x=320, y=170)
so, i have 2 buttons and enter box. I want the program to get the text from the enter box and if namemass list have that inside, then exit. in console program i would code it like that:
name = input()
namemass = ["dev", "Dev1"]
if name in namemass:
import sys
sys.exit()
else:
..........
how to do it using tkinter? thank you in advance!
To fetch the current entry text, use the get method:
current_text = Entry.get()
in your example you can just:
from tkinter import *
import sys
def destroy():
name = entry_name.get()
if name in namemass:
sys.exit()
root = Tk()
namemass = ["dev", "Dev1"]
entry_name = Entry(root)
entry_name.pack()
btn_cancel = Button(root, text="cancel", command=destroy)
btn_cancel.pack()
btn_ok = Button(root, text="ok")
btn_ok.pack()
root.mainloop()
Much easier for Python 3.8, using Walrus. Just add the function for _ok. And add command in btn_ok.
from tkinter import *
import sys
namemass = ["dev", "Dev1"]
def destroy():
#sys.exit()
root.destroy()
def _ok():
if(name_in_list := entry_name.get()) in namemass:
sys.exit()
root = Tk()
entry_name = Entry(root)
entry_name.pack()
btn_cancel = Button(root, text="cancel", command=destroy)
btn_cancel.pack()
btn_ok = Button(root, text="ok", command=_ok)
btn_ok.pack()
root.mainloop()

Pass values to python script with Tkinter

So I've written a python script that uses the PIL library to format a png passed to it. I want to make the script more user friendly and after looking around I saw the Tkinter library which seemed perfect. Basically the script has five variables that I need to pass to it for it to run. I'm currently using the raw_input() function to asking the user for the following variables:
path_to_png
title
subtitle
source
sample_size
Once received the script runs and exports the formatted png. I've used Tkinter to build those basic inputs as you can see from the picture below but I don't know how to pass the inputed text values and the file path from the choose png button to their respective variables.
from Tkinter import *
from tkFileDialog import askopenfilename
from tkMessageBox import *
app = Tk()
app.title("Picture Formatting")
app.geometry('500x350+200+200')
#
def callback():
chart_path = askopenfilename()
return
def title_data():
title_data = chart_title
return
errmsg = 'Error!'
browse_botton = Button(app, text="Choose png", width=15, command=callback)
browse_botton.pack(side='top', padx=15, pady=15)
# Get chart data
chart_title = StringVar()
title = Entry(app, textvariable = chart_title)
title.pack(padx=15, pady=15)
chart_subtitle = StringVar()
subtitle = Entry(app, textvariable = chart_subtitle)
subtitle.pack(padx=15, pady=15)
chart_source = StringVar()
source = Entry(app, textvariable = chart_source)
source.pack(padx=15, pady=15)
chart_sample_size = IntVar()
sample_size = Entry(app, textvariable = chart_sample_size)
sample_size.pack(padx=15, pady=15)
submit_button = Button(app, text="Submit", width=15)
submit_button.pack(side='bottom', padx=15, pady=15)
app.mainloop()
I have tried your code, and I added some lines:
from Tkinter import *
from tkFileDialog import askopenfilename
from tkMessageBox import *
app = Tk()
app.title("Picture Formatting")
app.geometry('500x350+200+200')
#
def callback():
global chart_path
chart_path = askopenfilename()
return
def title_data():
title_data = chart_title
return
def calculate():
chart_title = title.get()
chart_subtitle = subtitle.get()
chart_source = source.get()
chart_sample_size = sample_size.get()
print "chart_path : ", chart_path
print "chart_title : ", chart_title
print "chart_subtitle : ", chart_subtitle
print "chart_source : ", chart_source
print "chart_sample_size : ", chart_sample_size
#Call your functions here
return
errmsg = 'Error!'
# Get chart data
chart_path = ''
browse_botton = Button(app, text="Choose png", width=15, command=callback)
browse_botton.pack(side='top', padx=15, pady=15)
chart_title = StringVar()
title = Entry(app, textvariable = chart_title)
title.pack(padx=15, pady=15)
chart_subtitle = StringVar()
subtitle = Entry(app, textvariable = chart_subtitle)
subtitle.pack(padx=15, pady=15)
chart_source = StringVar()
source = Entry(app, textvariable = chart_source)
source.pack(padx=15, pady=15)
chart_sample_size = IntVar()
sample_size = Entry(app, textvariable = chart_sample_size)
sample_size.pack(padx=15, pady=15)
submit_button = Button(app, text="Submit", width=15, command=calculate)
submit_button.pack(side='bottom', padx=15, pady=15)
app.mainloop()
I think the problem you want to ask is how to get the text values in the entry widgets and get the path text from the askopenfilename() function. You can use the method Entry.get() to get the text value in certain entry widget.
And you can just use str = askopenfilename() to get the path's text value. But because this line of code is written in a function, you need to declare that it is a global variable or create a class to contain them, or the interpreter will consider that variable is an local variable and it will not be passed to the function calculate() which I added.
Since you didn't use a class to contain the variables, I also use the variables as global variables. It is not a good design. You can consider to create a class instead.
In order to receive the value from an entry widget, you would want to use the get() function. The get() function will return whatever is in the entry widget. For instance in your case: response = sample_size.get() will set the variable response to 0. See this page for more documentation on the entry widget.
Hope this helped.

Python Tk _tkinter.TclError: invalid command name ".42818376"

I am getting the error mentioned in the title of the post I really just want this to work. Been working on this problem for a while now and it is frustrating. My ultimate goal is to obtain the values for the varables text, chkvar, and v.
Thanks to anyone who can reply and help on this!!
#!C:/Python27/python.exe
from Tkinter import *
import ImageTk, Image
root = Tk()
root.title('HADOUKEN!')
def killwindow():
root.destroy()
text = Text(root, height=16, width=40)
scroll = Scrollbar(root, command=text.yview)
text.configure(yscrollcommand=scroll.set)
text.grid(sticky=E)
scroll.grid(row=0,column=1,sticky='ns')
text.focus()
chkvar = IntVar()
chkvar.set(0)
c = Checkbutton(root, text="CaseIt", variable=chkvar)
c.grid(row=1,column=0,sticky=W)
v = ""
radio1 = Radiobutton(root, text="Src", variable=v, value=1)
radio1.grid(row=1,column=0)
radio1.focus()
radio2 = Radiobutton(root, text="Dst", variable=v, value=2)
radio2.grid(row=2,column=0)
b1 = Button(root, text="Submit", command=killwindow)
b1.grid(row=1, column=2)
img = ImageTk.PhotoImage(Image.open("Hadoken.gif"))
panel = Label(root, image = img)
panel.grid(row=0, column=2)
root.mainloop()
tk1 = text.get(text)
tk2 = chkvar.get(chkvar)
tk3 = v.get(v)
print tk1
print tk2
print tk3
Once mainloop exits, the widgets no longer exist. When you do text.get(text), you're trying to access a deleted widget. Tkinter simply isn't designed to allow you to access widgets after the main window has been destroyed.
The quick solution is to modify killwindow to get the values before it destroys the window, and store them in a global variable which you can access after mainloop exits.
The program didn't make it through the variable getting, so it never reported the incorrect method calls. I made a few changes to the original code (added a textval StringVar, and changed the v variable to another IntVar). I had a feeling the "associated variables" wouldn't have a problem, and didn't need to be included in the killwindow code. The only variable I grab in killwindow is the text data.
Working code (changed lines marked with #++) :
#!C:/Python27/python.exe
from Tkinter import *
import ImageTk, Image
root = Tk()
root.title('HADOUKEN!')
textval = StringVar() #++ added
def killwindow():
textval.set(text.get('1.0',END)) #++ grab contents before destruction
root.destroy()
text = Text(root, height=16, width=40)
scroll = Scrollbar(root, command=text.yview)
text.configure(yscrollcommand=scroll.set)
text.grid(sticky=E)
scroll.grid(row=0,column=1,sticky='ns')
text.focus()
chkvar = IntVar()
chkvar.set(0)
c = Checkbutton(root, text="CaseIt", variable=chkvar)
c.grid(row=1,column=0,sticky=W)
v = IntVar() #++ changed
v.set(1) #++ initial value
radio1 = Radiobutton(root, text="Src", variable=v, value=1)
radio1.grid(row=1,column=0)
radio1.focus()
radio2 = Radiobutton(root, text="Dst", variable=v, value=2)
radio2.grid(row=2,column=0)
b1 = Button(root, text="Submit", command=killwindow)
b1.grid(row=1, column=2)
img = ImageTk.PhotoImage(Image.open("Hadoken.gif"))
panel = Label(root, image = img)
panel.grid(row=0, column=2)
root.mainloop()
# windows are destroyed at this point
tk1 = textval.get() #++ changed
tk2 = chkvar.get() #++ changed
tk3 = v.get() #++ changed
print tk1
print tk2
print tk3

Categories