0

I am trying to label my button dynamically based on the database results. So in this case the button would be labeled '23'

Database

| id | number |

| 1 | 23

from tkinter import *
import pymysql as mdb

from tkinter import ttk


#functions
def functionHolder():
    print("do nothing function holder")


root = Tk()
dbi = mdb.connect("localhost",port=3306, user="access", passwd="***", db="index_db" )
cursor = dbi.cursor()

cursor.execute("""SELECT number FROM caution_elements WHERE id = 1 """)
dbi.commit()
data = cursor.fetchone()[0]
dbi.close()

result =str("%s " % data)



 varButt = Button(root,textvariable=data, command=functionHolder)
 varButt.pack()

 root.mainloop()

Button should be labeled [23] I currently get a blank button and no errors

4
  • 1
    you don't need str("%s " % data) to convert to string - use str(data) or "%s " % data if you need space at the end. Commented Dec 6, 2017 at 1:26
  • 1
    textvariable= expects special class tkinter.StringVar(). If you have your numer in result then use text=result or even text=data Commented Dec 6, 2017 at 1:28
  • What do you mean by "labeled [23]"? Do you mean the text on the button? Commented Dec 6, 2017 at 1:44
  • result =str(data) varButt = Button(root,text=result, command=functionHolder) varButt.pack() Worked!!! Thanks Commented Dec 6, 2017 at 2:33

1 Answer 1

3

A textvariable option of tkinter widgets require special variable classes such as StringVar, BooleanVar or IntVar. Their values can be accessed using get method and their values can be changed using set as in:

import tkinter as tk

root = tk.Tk()

data = tk.StringVar()
data.set("This")

def change():
    if data.get() == "This":
        data.set("That")
    else:
        data.set("This")

tk.Label(root, textvariable=data).pack()
tk.Button(root, text="Change", command=change).pack()

root.mainloop()

If you are not sure about using class variables another example without them would be:

import tkinter as tk

root = tk.Tk()

data = "This"

def change():
    global data
    if data == "This":
        data = "That"
        a_label['text'] = data
    else:
        data = "This"
        a_label.config(text=data)


a_label = tk.Label(root, text=data)
a_label.pack()
tk.Button(root, text="Change", command=change).pack()

root.mainloop()

Both of the code pieces do the same thing except that when you change data's value, in the first example you're also changing text displayed by the label, and in the second example you need to explicitly update a_label's text option.


Also note that you can use a_widget.config(option=value), a_widget.configure(option=value), a_widget['option'] = value interchangeably given that you're modifying only one option.

Sign up to request clarification or add additional context in comments.

2 Comments

Further, when you tie the Label text to a StringVar() like data, when you programmatically update the StringVar value with a call to the set() method data.set('hello'), you will see the text on the Button magically change, too. That's part of the beauty of the event-driven GUI world of Tkinter. Once configured properly, you can make a change in one place, and it can propagate throughout your GUI.
Thanks that makes a lot of sense.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.