I'm sure someone is going to mark this as a duplicate the second I post it, but I assure you, I've been looking for hours. I'm brand new to tkinter so bear with me as I'd like a really straightforward answer if possible. Anything related to this specifically was a bit complex for me right now and I didn't feel it answered my question.
I know how to have a Label update with textvariable and StringVar. However, I'm trying to update an integer and I can't seem to figure it out for some reason. The number updates and prints through the console but I can't figure out the right syntax to get it to show up on the interface. It either just shows 0 (as the default variable shows) or there is no text there at all depending on what I've changed the code to)
So all I'm doing is simply incrementing a number. Let's leave it at that for now. And if anyone has any resources to more straightforward documentation please let me know because it seems tkinter in general is pretty obscure in documentation online as far as I can tell.
my_count = 0
def increase_mycount():
global my_count
increment = int(my_count) + 1
my_count = str(increment)
print(my_count)
Label(root, textvariable=my_count).grid(row=2, column=1)
Button(root, text="+", command=inc_mycount).grid(row=3, column=2)
This is where it's at right now, I've tried changing my_count into an IntVar and also a StringVar and I get an error saying I can't use + with int and intvar or int with stringvar
Is there something really simple I'm missing? I'm struggling finding comprehensive documentation on tkinter. It's easy to find Python information but not this really.. I'm in the process of organizing all the info I'd like into some google docs.
Thank you for any time you give. This seems like it should be a really simple thing to do but I've only worked with engines that update things for me. I'm only use tkinter, a .py file, and cmd for this.
And another note, I can't use .set() for this either it seems, like I could for a string. So I'm just struggling with the syntax unless there is a different method for numbers on labels.
You have to use one of tkinter's variable objects when using textvariable. In this case, IntVar.
import tkinter as tk
root = tk.Tk()
my_count = tk.IntVar()
def increase_mycount():
current = my_count.get()
my_count.set(current+1)
tk.Label(root, textvariable=my_count).grid(row=2, column=1)
tk.Button(root, text="+", command=increase_mycount).grid(row=3, column=2)
root.mainloop()
Related
I have a scale and an input field which both control the same variable to give the user choice of which one they'd like to use. I've coded it a bit like this:
def scale_has_moved(value):
entry_field.delete(0, END)
entry_field.insert(0, str(float(value)))
# Other functions I want the code to do
def entry_field_has_been_written(*args):
value = float( entry_field.get() )
scale.set(value)
This works, when I move the scale the entry_field gets written in and vice versa, and the other functions I want the code to do all happen. The obvious problem is the functions call each other in a loop, so moving the scale calls scale_has_moved() which calls the additional functions within and writes in the entry field, then because the entry field has been written in entry_field_has_been_written() gets called which in turn calls scale_has_moved() again, it doesn't go in an endless loop but it does everything at least twice everytime which affects performance.
Any clue how I'd fix this? Thank you
If you use the same variable for both widgets, they will automatically stay in sync. You don't need your two functions at all. The following code illustrates the technique.
import tkinter as tk
root = tk.Tk()
var = tk.IntVar(value=0)
scale = tk.Scale(root, variable=var, orient="horizontal")
entry = tk.Entry(root, textvariable=var)
scale.pack(side="top", fill="x")
entry.pack(side="top", fill="x")
root.mainloop()
I need to fetch one number from a column
cursor.execute('''SELECT vacas FROM animales''')
cantidad1 = cursor.fetchone()
Then I need this number to be shown in a Tkinter Label:
cantidad = Label (ventana, textvariable=cantidad1).grid(row=1, column=3)
And I have a refresh button in order to update the data.
ref = Button (ventana, text="Refresh", command=update )
The problem is that the Label is always blank, even when I press button and call Update():
Here is the complete code:
cantidad1 = 0
ventana = Tk()
cursor = db.cursor()
def update():
cursor.execute('''SELECT vacas FROM animales''')
cantidad1 = cursor.fetchone()
print (cantidad1[0]) #The number shown in command is right, but blank in tkinter.
ref = Button (ventana, text="Refresh", command=update )
ref.grid(row=3, column=2)
cantidad = Label (ventana, textvariable=cantidad1).grid(row=1, column=3)
ventana.mainloop()
https://imgur.com/AvsNAuL "Screenshot tkinter blank"
Using textvariable in Tkinter can be handy, but it requires thinking a bit in Tcl/Tk style instead of Python style. You may want to read up on it I'm not sure where the best docs are, but Entry and The Variable Classes in the old book are probably a good place to start.
Anyway, a textvariable binding has to refer to a Tcl variable, like a StringVar. Somewhere before creating that Label with textvariable=cantidad1 you need to do something like this:
cantidad1 = StringVar('0')
And then, instead of this:
cantidad1 = cursor.fetchone()
… you have to do this:
cantidad1.set(cursor.fetchone())
What you're doing is changing the name cantidad1 to refer to the new result, but what you need to do is leave it referring to the StringVar and change the value of the StringVar, so Tk can see it and update the label.
While we're at it, I think you actually want something like cursor.fetchone()[0]; otherwise you're trying to use a row (probably a list or other sequence, not a string).
Finally, you could use an IntVar here. That would allow you to initialize it to 0 instead of '0', but then of course you have to set it to int(spam) instead of just spam, and you may need some error handling to deal with what happens if the database returns Null.
If all of this is Greek to you (or, worse, Tcl), the other option is to just not use Tk variables:
cantidad = Label(ventana, text='0').grid(row=1, column=3)
Notice that the difference here is that I set the initial text, rather than setting a textvariable.
So now, every time you fetch new data, you'll have to manually update (re-config) the label's text, like this:
cantidad1 = ... # code that just gets a normal Python string
cantidad.config(text=cantidad1)
This is much less idiomatic Tk code, and arguably less idiomatic Tkinter code—but it's a lot more Pythonic, so it may be easier for you to read/debug/write. (Notice that the first line is exactly what you instinctively wrote, which was wrong with your original design, hence your question, but would be right with the explicit-update design.)
—-
There are other problems in the code that I haven’t fixed. For example, the grid method on widgets doesn’t return the widget, it returns None. You’re doing it right for ref, but not for cantidad. Your original code never actually referred to cantidad, so that wasn't a problem, but if you, e.g., switch to using manual updates instead of automatic variables, you're going to get a confusing exception about calling configure on None.
My problem is that when creating a Radiobutton it is automatically checked and i can't uncheck it. I create it inside a frame of x and y dimensions.
I've tried the .deselect() function but it changes nothing
(Python 3.6)
code:
frm = ttk.Frame(root)
frm.place(x=0,y=0,width=1000,height=1000)
Ek = ttk.Radiobutton(frm,text="text")
Ek.place(x=100,y=400)
And photo of it:
photo
First, if we just wanted to modify your code to give us a single unchecked radio button all by itself, this would do the trick.
from tkinter import Tk, IntVar, Radiobutton, mainloop, ttk
root = Tk()
frm = ttk.Frame(root)
frm.place(x = 0, y = 0, width = 1000, height = 1000)
v = IntVar()
Ek = ttk.Radiobutton(frm, text = "text", variable = v, value = 1)
Ek.place(x = 100, y = 100)
mainloop()
Aside from the boilerplate for setup at the beginning and end, the only thing we had to change in your original code was to add the arguments variable = v, value = 1 to the Radiobutton call.
Those extra arguments don't really make sense in isolation, for the same reason that it doesn't generally make sense to have a single radio button. Once we add two of them, we can see what's going on a bit better.
In the documentation #Stack posted (this thing), the first code sample looks like this:
from Tkinter import *
master = Tk()
v = IntVar()
Radiobutton(master, text="One", variable=v, value=1).pack(anchor=W)
Radiobutton(master, text="Two", variable=v, value=2).pack(anchor=W)
mainloop()
If we run that, we get two unchecked radio buttons by default. If we then change the value=1 part to value=0, the first radio button shows up checked, and if we change value=2 to value=0, the second radio button shows up checked. So value=0 seems to give us buttons that are checked by default, but we don't know why yet. Let's experiment a bit more.
If we try to delete pieces in the new sample until we get back to something more closely resembling what you wrote originally, we can sort of see what happened. Deleting the value arguments entirely and running it like this:
Radiobutton(master, text="One", variable=v).pack(anchor=W)
Radiobutton(master, text="Two", variable=v).pack(anchor=W)
leaves us with neither button checked by default, though then further deleting the variable arguments to make the code look like your original call:
Radiobutton(master, text="One").pack(anchor=W)
Radiobutton(master, text="Two").pack(anchor=W)
gives us two buttons that are both checked by default, which gets us back to your original problem.
Basically, we're running into various odd corner cases here because we just started fiddling with code and forgot what a radio button actually represents.
What the concept of a radio button represents in the first place is the value of a variable. Not the entire variable, just one of the things it might be equal to. And the set of radio buttons itself, taken together, gives us a visual representation of a discrete variable: a thing that can be in 1 of N states.
So the API for Radiobuttons, naturally, is asking us for some information like "what python variable do you want us to use to hold these values?" (that's roughly the variable keyword) and "what values do you want us to glue to each of these buttons behind the scenes to distinguish the different states?" (that's the value keyword).
As expected, the code works best in the case above where the values were 1 and 2, because in that case the code is properly reflecting what a radio button actually is, conceptually. When we collide the values or set them to zero or leave them out entirely, things get a bit weird and less predictable because we're then dealing with the implementation details of the tkinter API, rather than with the simple concept of a radio button that the API is meant to implement.
Laptop's about to die, so I'm gonna go ahead and hit send. Hope that wasn't too wordy. Good luck. :)
Radiobuttons need to be associated with one of the special Tkinter variables (StringVar, etc), and are designed to work in groups of two or more. If you don't specify a variable, one will be created for you. The default value of a Radiobutton is the empty string, which is also the default variable will be set to.
Just assign a different value to the declared variable
from tkinter import Tk, IntVar, Radiobutton, mainloop, ttk
root = Tk()
frm = ttk.Frame(root)
frm.place(x=0,y=0,width=100,height=400)
language=StringVar(value='portuguese')
Ek = ttk.Radiobutton(frm,variable="language",text="spanish",value="spanish")
Ek.place(x=10,y=50)
Ek = ttk.Radiobutton(frm,variable="language",text="english",value="english")
Ek.place(x=10,y=85)
mainloop()
I'm pretty new in programming, so I don't know many basics. I tried searching everywhere, but didn't get the answer I need.
In this website I found a similar problem, but it was for Python3.
I could change to python 3 interpreter, but then I would have to rewrite the code, due to syntax.
Anyway, my problem is, I want to write down text in a textbox and I need it to be taken for use (for example print it out or use it as name in a linux command).
I tried raw_input, even tried to add .get commands.
.get didn't work for me and input or raw_input input would do nothing, they would not print out the text and my programming gets stuck
My code
def filtras():
root = Tk()
root.title("Filtravimas pagal uzklausa")
root.geometry("300x100")
tekstas = Text(root, height=1, width=15).pack(side=TOP)
virsus = Frame(root)
virsus.pack()
apacia = Frame(root)
apacia.pack(side=BOTTOM)
myg1 = Button(virsus, text="Filtruoti", command=lambda: gauti())
myg1.pack(side=BOTTOM)
def gauti():
imti=input(tekstas)
print(imti)
Your problem is a common mistake in this line:
tekstas = Text(root, height=1, width=15).pack(side=TOP)
Geometry methods such as .pack and .grid return None, and None.get does not work. Instead do the same as you did for Frame and Button.
tekstas = Text(root, height=1, width=15)
tekstas.pack(side=TOP)
Now tekstas.get() and other Text methods will work.
This code does not touch on 2 <=> 3 syntax changes. The only issue is the name Tkinter versus tkinter and other module name changes.
Please read about MCVEs. Everything after the Text widget is just noise with respect to your question.
input and raw_input get characters from stdin, which is normally the terminal. Except for development and debugging, do not use them with GUI programs, and only use them if running the GUI program from a terminal or IDLE or other IDE. Ditto for print.
I've recently started using classes in my programs and I've got 2 problems/questions.
Following the question I've pasted not the whole code, but only the part about which I need advise about.
1)the only way I have found to access to the value the user will input in my GUI's entry widget is to declare the list ac global, so I can later append the various entry widget for further reference. I tried it in my printer function and it worked. I was just wondering if there is another way to manage the problem because using a global variable, according to what I read on the net, is not the very best idea.
2)I've got some problem with doing the same thing with the optionwidget. I can't find a way to get the data because of variable referencing problems. Assuming that I'm managing this thing the best way an apprentice of Python could, how can I do that?
If I wasn't clear, please let me know. I'm not a native English speaker and I still have to get confidence with the language.
from tkinter import *
root = Tk ()
root.title("GENERATOR")
root.geometry("300x300")
class entryandlabel:
global ac
ac=[]
def printer():
#as an example
print(ac[2].get())
def createentry(lista):
#entry widget creation
i=1
for a in lista:
entry = Entry (root)
entry.grid(row=i, column=1, sticky = W)
ac.append(entry)
i+=1
def createoption(lista, c):
#option widget creation
a = StringVar(root)
a.set("Selezionare")
b = OptionMenu(*(root, a) + tuple(lista))
b.grid(row=c, column=1)