Unable to make a button (created using tkinter) quit automatically - python

I've written a script using tkinker in python. When I run the script, it receives an input and print that to the console. It is working great.
What I wish to do is add any functionality to my existing script in such a way so that after filling in the inputbox when I press the get button, it will print the value in the console and quits automatically. Once again, my existing script is capable of printing values. I need to make that button quit as soon as the printing is done. Any help on this will be highly appreciated.
Here is what I've tried so far:
from tkinter import *
master = Tk()
e = Entry(master)
e.pack()
e.focus_set()
callback = lambda : get_val(e.get())
get_val = lambda item: print(item) #this extra function is for further usage
Button(master, text="get", width=10, command=callback).pack()
master.mainloop()
This is how the inputbox looks like:

Modify the callback function as:
def callback():
get_val(e.get()) #Gets your stuff done
master.destroy() #Breaks the TK() main loop
exit() #Exits the python console
Here,master.destroy() breaks the master.mainloop() loop and thus terminates the GUI and finally exit() makes it exit the python console.

Maintaining your lambda syntax:
callback = lambda : (print(e.get()), master.destroy())
The key is to call master.destroy().

Related

How to detect if any button is pressed while we are running an endless loop in Python GUI

I have four buttons on GUI with different functions. I built them like:
button1 = TKinter.Button(btnFrame, text = "bt1", command = bt1func)
I also have a function sensor() which has to be run all the time at first, if any button is pressed, I hope we can break the loop of calling the sensor() and process the button's function. How could we implement it? Thanks
I referred this post: tkinter root.mainloop with While True loop
We can use root.after() to solve this kind of problem, for example:
def sensor():
root.after(200, sensor)
root.after(200, sensor)
root.mainloop()

Not able to to call function with button in tkinter

I'm new to Tkinter, and also new to this forum. I am trying to learn to use Tkinter, and I have a problem!
I want to save some text to a text file by writing the text and then press a button to run a function that saves the info. But it seems like my "command" does not start the function.
def ny_artikel():
artikel_data = open ("artikel_databas.txt", "w")
artikel_data.write(ny_artikel.get())
artikel_data.close ()
spara_artikel = Button(new_product_window, text ="Save new article", command = ny_artikel)
spara_artikel.grid(row=7, column=1)
ny_artikel is an entry box used in my program, but I think it's too many rows to paste it all in here.
When I press the button, nothing at all happens. Not even an error message.
I assume, that the code in your answer is only part of your python file. I tried it out with Entry e in my example and it works right:
import tkinter
def ny_artikel():
with open('artikel_databas.txt', 'w') as artikel_data:
artikel_data.write(e.get())
main = tkinter.Tk()
e = tkinter.Entry(main)
e.grid(row=0, column=0)
spara_artikel = tkinter.Button(main, text ="Save new article", command = ny_artikel)
spara_artikel.grid(row=1, column=0)
main.mainloop()
As alternative I used 'with' 'as' in ny_artikel() function, which automatically closes the file. Using file.close() works fine as well.
What is the python keyword "with" used for?

How can I perform an action after mainloop() has been called in Tkinter?

I want to make a GUI command line using the Text widget. For debugging purposes, I am trying to print whatever the user types into the separate GUI window to the system terminal. I know that it is frowned upon to mix GUI and Text Based commands into the same script, but I am just debugging, so forgive me 😉
Here is my code:
from Tkinter import *
main = Tk()
console = Text(main)
console.pack()
main.mainloop()
while True:
text = console.get("1.0", "end-1c")
print(text)
My current issue is that when the mainloop starts, (of course) the while loop doesn't. If I were to move the while loop in front of the mainloop call, it would never call mainloop. I really want it to continuously check for new text.
Is there a way to like "pause" the mainloop, or just carry out the command, maybe on a new thread or something?
I want to avoid using main.after(), but if that is the only way, then so be it. ¯\(°_o)/¯
I recommend using main.after(), as it's the canonical way to do things like this in Tkinter. The following will also ensure that it only tries to print every second, instead of as fast as the console can handle it (as the while loop in your code would do if it worked).
def print_console():
print(console.get("1.0", "end-1c"))
main.after(1000, print_console)
print_console()
main.mainloop()
You can also bind widgets to "Modified"
from Tkinter import *
class TextModified():
def __init__(self):
root = Tk()
self.txt = Text(root)
self.txt.pack()
self.txt.focus_set()
self.txt.bind('<<Modified>>', self.changed)
Button(text='Exit', command=root.quit).pack()
root.mainloop()
def changed(self, value=None):
flag = self.txt.edit_modified()
if flag: # prevent from getting called twice
print "changed called", self.txt.get("1.0", "end-1c")
## reset so this will be called on the next change
self.txt.edit_modified(False)
TM=TextModified()

python label not changing dynamically

I want to see continuously changing value of label in tkinter window. But I'm not seeing any of it unless I make a keyboard interrupt in MS-CMD while running which shows me the latest assigned value to label. Plz tell me ..What's going on & what's the correct code ??
import random
from Tkinter import *
def server() :
while True:
x= random.random()
print x
asensor.set(x)
app=Tk()
app.title("Server")
app.geometry('400x300+200+100')
b1=Button(app,text="Start Server",width=12,height=2,command=server)
b1.pack()
asensor=StringVar()
l=Label(app,textvariable=asensor,height=3)
l.pack()
app.mainloop()
The function server is called when you click the button, but that function contains an infinite loop. It just keep generating random numbers and sending these to asensor. You are probably not seeing any of it because the server function is run in the same thread as the GUI and it never gives the label a chance to update.
If you remove the while True bit from your code, a new number will be generate each time you click the button. Is that what you wanted to do?
Edit after comment by OP:
I see. In that case your code should be changed as follows:
import random
from Tkinter import Tk, Button, Label, StringVar
def server():
x = random.random()
print x
asensor.set(x)
def slowmotion():
server()
app.after(500, slowmotion)
app = Tk()
app.title("Server")
app.geometry('400x300+200+100')
b1 = Button(app, text="Start Server", width=12, height=2, command=slowmotion)
b1.pack()
asensor = StringVar()
asensor.set('initial value')
l = Label(app, textvariable=asensor, height=3)
l.pack()
app.mainloop()
I also introduced a new function, slowmotion, which does two things: 1) calls server, which updates displays the value, and 2) schedules itself to be executed again in 500ms. slowmotion is first ran when you first click the button.
The problem with your code was that it runs an infinite loop in the main GUI thread. This means once server is running, the GUI will not stop and will not get a chance to display the text you asked it to display.

Call back in Python

Could some explain how call back methods work, and if possible, give me an example in Python? So as far as I understand them, they are methods which are provided by the user of an API, to the API, so that the user doesn't have to wait till that particular API function completes. So does the user program continue executing, and once the callback method is called by the API, return to point in the program where the callback method was provided? How does a callback method essentially affect the 'flow' of a program?
Sorry if I'm being vague here.
Callbacks are just user-supplied hooks. They allow you to specify what function to call in case of certain events. re.sub has a callback, but it sounds like you are dealing with a GUI, so I'll give a GUI example:
Here is a very simple example of a callback:
from Tkinter import *
master = Tk()
def my_callback():
print('Running my_callback')
b = Button(master, text="OK", command=my_callback)
b.pack()
mainloop()
When you press the OK button, the program prints "Running my_callback".
If you play around with this code:
from Tkinter import *
import time
master = Tk()
def my_callback():
print('Starting my_callback')
time.sleep(5)
print('Ending my_callback')
def my_callback2():
print('Starting my_callback2')
time.sleep(5)
print('Ending my_callback2')
b = Button(master, text="OK", command=my_callback)
b.pack()
b = Button(master, text="OK2", command=my_callback2)
b.pack()
mainloop()
you'll see that pressing either button blocks the GUI from responding until the callback finishes. So the "user does have to wait till that particular API function completes".

Categories