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

Raymond
  • 40
  • 8
  • 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. – furas Dec 06 '17 at 01:26
  • 1
    `textvariable=` expects special class `tkinter.StringVar()`. If you have your numer in `result` then use `text=result` or even `text=data` – furas Dec 06 '17 at 01:28
  • What do you mean by "labeled [23]"? Do you mean the text on the button? – Bryan Oakley Dec 06 '17 at 01:44
  • result =str(data) varButt = Button(root,text=result, command=functionHolder) varButt.pack() Worked!!! Thanks – Raymond Dec 06 '17 at 02:33

1 Answers1

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.

Nae
  • 14,209
  • 7
  • 52
  • 79
  • 1
    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. – GaryMBloom Dec 06 '17 at 02:00
  • 1
    Thanks that makes a lot of sense. – Raymond Dec 06 '17 at 02:34