Im trying to make a little program that endlessly prints out numbers inside GUI window, I can not find a way to print the out put of the function in a text box inside the GUI window instead of the python shell, please help, here is my code so far...
import sys
from tkinter import *
root = Tk()
def number(event):
x = 420
while True:
x +=420
print(x^70)
button_1 = Button(root, text="Start...")
button_1.bind("<Button-1>", number)
button_1.pack()
root.mainloop()
Thanks Harvey
You'll find it hard to constantly insert a value into a widget. The widget does not update with each insert. You can think of it has having a temporary variable for it. It can be accessed during the loop (as shown with print). However you'll notice that the widget itself doesn't update until the loop is over. So if you have while True then your widget will never update, and so you won't have the numbers streaming into the widget.
import sys
from tkinter import *
root = Tk()
def number():
x = 420
while x < 8400: # Limit for example
x +=420
textbox.insert(END, str(x^70)+'\n')
print(textbox.get(1.0, END)) # Print current contents
button_1 = Button(root, text="Start...", command=number) #Changed bind to command, bind is not really needed with a button
button_1.pack()
textbox = Text(root)
textbox.pack()
root.mainloop()
Related
I was trying to make a stopwatch in python but every time it stops working beacause of overflow, can someone please fix this??
Code:
import time
from tkinter import *
cur=time.time()
root = Tk()
def functio():
while True:
s = time.time()-cur
l1 = Label(root,text=s)
l1.pack()
l1.destroy()
time.sleep(0.5)
Button(root,text='Start',command=functio).pack()
root.mainloop()
The while loop will block tkinter mainloop from handling pending events, use after() instead.
Also it is better to create the label once outside the function and update it inside the function:
import time
# avoid using wildcard import
import tkinter as tk
cur = time.time()
root = tk.Tk()
def functio():
# update label text
l1['text'] = round(time.time()-cur, 4)
# use after() instead of while loop and time.sleep()
l1.after(500, functio)
tk.Button(root, text='Start', command=functio).pack()
# create the label first
l1 = tk.Label(root)
l1.pack()
root.mainloop()
Note that wildcard import is not recommended.
Flow of execution can never exit your endless while-loop. It will endlessly block the UI, since flow of execution can never return to tkinter's main loop.
You'll want to change your "functio" function to:
def functio():
s = time.time()-cur
l1 = Label(root,text=s)
l1.pack()
l1.destroy()
root.after(500, functio)
That being said, I'm not sure this function makes much sense: You create a widget, and then immediately destroy it?
You'll want to do something like this instead:
import time
from tkinter import *
root = Tk()
def functio():
global timerStarted
global cur
# check if we started the timer already and
# start it if we didn't
if not timerStarted:
cur = time.time()
timerStarted = True
s = round(time.time()-cur, 1)
# config text of the label
l1.config(text=s)
# use after() instead of sleep() like Paul already noted
root.after(500, functio)
timerStarted = False
Button(root, text='Start', command=functio).pack()
l1 = Label(root, text='0')
l1.pack()
root.mainloop()
I have a large list of environments loaded into an OptionMenu. When you open it, it will immediately close once you let go of the mouse button if the opened menu reaches outside of the screen. Is there any way to deal with this? (for example making it smaller and scrollable or deactivating said function) I tested this on Linux20.04 in case it is different on windows. Or can someone mention a dropdown-menu that doesn't have that problem.
#!/usr/bin/env python3
from tkinter import *
class Dropdown:
def __init__(self,options, master):
self.variable = StringVar(master)
self.variable.set(options[0]) # default value
self.menue = OptionMenu(master, self.variable, *options)
self.menue.pack()
typ = [
"Giftpflanze",
"Übernatürliche Pflanze",
"Heilpflanze",
"Nutzpflanze",
"Wehrende Pflanze",
"physische Wirkung",
"psychische Wirkung"
]
# Rad Suchschwierigkeit
# Rad Bestimmschwierigkeit
master = Tk()
d1 = Dropdown(typ,master)
def ok():
print ("value is:" + d1.variable.get())
button = Button(master, text="OK", command=ok)
button.pack()
mainloop()
So you can try it out on your own (just make sure it actually would reach out of your screen).
Here is a video: https://imgur.com/5Suqtiq
I have a problem to detect/check button press in python tkinter !
I have a variable click i want that if my button is clicked then it becomes True
for ex:
this is my code:
buttonClicked=False
myButton=Button()
I want something like this:
if myButton is pressed:
buttonClicked=True
Thanks for your help!
I am not aware of any internal tkinter method to check if a button is pressed.
However you could connect the Button with a function that changes the value of a global variable, like in the following:
from Tkinter import *
master = Tk()
def callback():
global buttonClicked
buttonClicked = not buttonClicked
buttonClicked = False # Bfore first click
b = Button(master, text="Smth", command=callback)
b.pack()
mainloop()
The code, changes the variable value from False to True (or reverse) every time you press the button.
I think that you could make a function to change the value of buttonClicked, and, when the button is clicked, it executes that function (whose only purpose is to change the value of buttonClicked).
The complete code could go as follows:
from tkinter import *
buttonClicked = False
def changeValue():
if buttonClicked:
buttonClicked=False
if not buttonClicked:
buttonClicked=True
tk = Tk()
btn = Button(tk, text="Put whatever text you want here, to tell the person what pressing the button will do", command=changeValue())
btn.pack()
If this answer help, I would appreciate you tell me! :).
This is a changed/edited version, with a loop for logic that changes the value of buttonClicked. In the part of code that says "if not buttonClicked:" you could change to an "else:" statement. #
Try this:
from tkinter import *
value = 1
def change_value():
global value
value -= 1
if value == 0:
print("button pressed")
value = 1
else:
pass
tk = Tk()
btn = Button(tk, text="your_text", command=change_value)
btn.pack()
Just put the code you want to run inside a function like this:
def when_clicked():
#code you want here
button = Button(window,command=when_clicked)
(may be a bit late but oh well)
I´m trying to use tkinter in order to show a popup window in front of all other windows that reminds me of something through a text displayed in the canvas. I want that the window pops up during some time, eg 5 seconds, and then dissapear for other time. I need this to repeat in a loop. When i tried to do it, a window appear but without the text and the specified dimensions. Here is the code:
from tkinter import *
from time import sleep as s
for i in range(5):
root = Tk()
root.lift()
root.attributes('-topmost',True)
canvas = Canvas(root,width=700,height=100)
canvas.pack()
canvas.create_text(350,50,text='Registrar rabia'+str(i),font=
('fixedsys','25'))
print('Hola')
s(1)
root.destroy()
s(1)
Also, is there a more pythonic way to do it?
EDIT:
from tkinter import *
root = Tk()
for _ in range(6):
#root.deiconify()
root.attributes('-topmost',True)
root.title("About this application...")
about_message = 'Este es el mensaje'
msg = Message(root, text=about_message)
msg.pack()
button = Button(root, text="Dismiss", command=root.withdraw)
button.pack()
root.after(1000)
It didn´t work. I need only one message and one button, and in the code above,
python shows 6 messages and 6 buttons... Also i need to put a delay between appearances but i can´t understand how to use the after method in this particular case.
I made a very simple gui that has a button and shows an image(.gif). My goal is to output another .gif whenever you press the button. There are 2 .gif files in my file directory and the point is to keep switching between these two whenever you press the button.
#Using python2.7.2
import Tkinter
root = Tkinter.Tk()
try:
n
except:
n = 0
def showphoto(par):
if par%2 == 0:
try:
label2.destroy()
except:
pass
photo = Tkinter.PhotoImage(file="masc.gif")
label2 = Tkinter.Label(image=photo)
label2.image = photo
label2.pack()
else:
try:
label2.destroy()
except:
pass
photo = Tkinter.PhotoImage(file="123.gif")
label2 = Tkinter.Label(image=photo)
label2.image = photo
label2.pack()
myContainer1 = Tkinter.Frame(root, width = 100, height = 100)
myContainer1.pack()
def callback(event):
global n
showphoto(n)
n = n + 1
button1 = Tkinter.Button(myContainer1)
button1["text"]= "Next pic"
button1["background"] = "green"
button1.bind("<Button-1>", callback(n))
button1.pack()
root.mainloop()
The current code just outputs the first image (masc.gif) but when I press the button it doesn't switch to the other image(123.gif). What am I doing wrong?
This can achieved much easier with classes as the class holds all the data necessary without the use of global variables.
import Tkinter as tk
from collections import OrderedDict
class app(tk.Frame):
def __init__(self,master=None, **kwargs):
self.gifdict=OrderedDict()
for gif in ('masc.gif','123.gif'):
self.gifdict[gif]=tk.PhotoImage(file=gif)
tk.Frame.__init__(self,master,**kwargs)
self.label=tk.Label(self)
self.label.pack()
self.button=tk.Button(self,text="switch",command=self.switch)
self.button.pack()
self.switch()
def switch(self):
#Get first image in dict and add it to the end
img,photo=self.gifdict.popitem(last=False)
self.gifdict[img]=photo
#display the image we popped off the start of the dict.
self.label.config(image=photo)
if __name__ == "__main__":
A=tk.Tk()
B=app(master=A,width=100,height=100)
B.pack()
A.mainloop()
Of course, this could be done more generally ... (the list of images to cycle through could be passed in for example), and this will switch through all the images in self.gifs ...
This approach also removes the necessity to destroy and recreate a label each time, instead we just reuse the label we already have.
EDIT
Now I use an OrderedDict to store the files. (keys=filename,values=PhotoImages). Then we pop the first element out of the dictionary to plot. Of course, if you're using python2.6 or earlier, you can just keep a list in addition to the dictionary and use the list to get the keys.
button1 = Tkinter.Button(myContainer1)
button1["text"]= "Next pic"
button1["background"] = "green"
button1.bind("<Button-1>", callback(n))
First, you bind the <Button-1> event to None (that's what callback(n) evaluates to). You should bind it to callback (no parentheses a.k.a the call operator).
Second, I suggest you change callback to not accept any arguments, remove the bind call and create your button as:
button1 = Tkinter.Button(myContainer1, command=callback)