Python reference with Tkinter label change text - python

I am trying to to change my Tkinter Label text from another function. Somehow I cannot reference the Label and therefore not changing the Label, only add a new on top of the old.
self.errorLabel['text'] = 'second' works inside the init-function of Window, but I need to be able to do it from another function, therefore a reference fault somehow.
This is my code:
import sys
from tkinter import *
from tkinter import ttk
class Window(Frame):
def __init__(self, master = None):
Frame.__init__(self, master)
self.master = master
self.errorLabel = Label(self, text="some text").grid(row=0)
self.init_window()
def init_window(self):
self.master.title("Example")
self.pack(fill=BOTH, expand=1)
goButton = Button(self, text="Go!", command=self.client_go).grid(row=1, column=1)
quitButton = Button(self, text="Close", command=self.client_exit).grid(row=1, column=0)
def client_exit(self):
exit()
def client_go(self):
self.errorLabel['text'] = 'second' # TypeError: 'NoneType' object does not support item assignment
self.errorLabel = Label(self, text="second").grid(row=0)
return
root = Tk()
root.geometry("800x500")
app = Window(root)
root.mainloop()

This is a very common error with tkinter code. Widget.grid returns None, so when you write:
self.errorLabel = Label(self, text="some text").grid(row=0)
self.errorLabel is None. Instead, create the widget and use it's geometry manager in separate lines of code:
self.errorLabel = Label(self, text="some text")
self.errorLabel.grid(row=0)

Related

tkinter: LabelFrame in a separate TopLevel window

My "simple" intention is to create a Dialog - launched by a button - where I have several LabelFrames with their radio button.
I tried with 1 LabelFrame with this simple code the radios appear in the main window, not in the dialogue one !!!! I cannot understand why. Please help.. ty for your attention
Here's the code:
import tkinter as tk
from tkinter import ttk
class PersonEmptyDocsDialog(tk.Toplevel):
def __init__(self, root,personid):
super().__init__(root)
self.personid = personid
self.code = tk.StringVar()
frame1 = ttk.Labelframe(self,text='testo').grid(column=0,row=0,padx=20,pady=20)
ttk.Radiobutton(frame1, text="Option 1", variable=self.code, value="0-0-0").pack()
ttk.Radiobutton(frame1, text="Option 1", variable=self.code, value="0-0-1").pack()
ttk.Radiobutton(frame1, text="Option 1", variable=self.code, value="0-0-2").pack()
self.ok_button = tk.Button(self, text="OK", command=self.on_ok).grid(column=0,row=1)
#self.ok_button.pack()
def on_ok(self, event=None):
self.destroy()
def show(self):
self.wm_deiconify()
self.wait_window()
return self.code.get()
class Example():
def __init__(self, root):
mainframe = ttk.Frame(root).pack(fill="both", expand=True)
self.root = root
ttk.Button(mainframe, text="Get Input", command=self.on_button).pack(padx=8, pady=8)
ttk.Label(mainframe, text="", width=20).pack(side="bottom", fill="both", expand=True)
def on_button(self):
string = PersonEmptyDocsDialog(self.root, 12).show()
print(string)
root = tk.Tk()
root.wm_geometry("400x200")
Example(root)
root.mainloop()
You cannot put in one line. You need to break this into in line 11
frame1 = ttk.Labelframe(self,text='testo')
frame1.grid(column=0,row=0,padx=20,pady=20)
Output:
Output after clicking Get input button:

ttk Style won't apply to frame in class

just started working with tkinter and i wanted to change the style of the frame but it won't. Can't figure it out so i'm asking you guys.
from tkinter import *
from tkinter import ttk
from tkinter import font
import currencyapi
class Currency():
def __init__(self, parent):
# App settings
parent.title("CoinyAPP")
icon = PhotoImage(file="icon.png")
parent.iconphoto(False, icon)
parent.eval("tk::PlaceWindow . center")
# Font settings
highlightFont = font.Font(
family='Helvetica', name='appHighlightFont', size=12, weight='bold')
# Widgets
self.frame1 = ttk.Frame(
parent, style="Frame1.TFrame").grid(row=0, column=0)
ttk.Label(self.frame1, text="Pick a base currency.", font=highlightFont).grid(
row=0, column=0, padx=48, pady=20)
ttk.Label(self.frame1, text="Pick currency to convert into.", font=highlightFont).grid(
row=0, column=2, padx=18, pady=20)
self.amount = StringVar()
currencyAmount = ttk.Entry(self.frame1, textvariable=self.amount)
currencyAmount.grid(row=1, column=1, padx=40)
self.baseCurrency = StringVar()
base = ttk.Combobox(self.frame1, textvariable=self.baseCurrency, justify='center',
values=list(currencyapi.currencyData['rates'].keys()))
base.grid(row=1, column=0)
base.current(46)
self.convertInto = StringVar()
convert = ttk.Combobox(self.frame1, textvariable=self.convertInto, justify='center',
values=list(currencyapi.currencyData['rates'].keys()))
convert.grid(row=1, column=2)
convert.current(0)
ttk.Button(self.frame1, command=self.currency_convertion,
text='Convert!').grid(row=2, column=1, padx=40, pady=15)
self.result = StringVar()
ttk.Label(self.frame1, font=highlightFont,
textvariable=self.result).grid(row=3, column=1, pady=5)
def currency_convertion(self, *args):
self.conv = currencyapi.currencyData['rates'].get(
self.convertInto.get())
self.amountNumber = self.amount.get()
self.base = currencyapi.currencyData['rates'].get(
self.baseCurrency.get())
Ans = (float(self.conv) * float(self.amountNumber)) / float(self.base)
self.result.set("%.2f" % Ans)
root = Tk()
s = ttk.Style()
s.configure("Frame1.TFrame", background='yellow',
foreground='blue')
Currency(root)
root.mainloop()
It's probably not very well written, sorry for that! Started programming few weeks ago.
Tried to put it into Currency class and outside, both didn't work.
It's possible that the problem is here:
self.frame1 = ttk.Frame(parent, style="Frame1.TFrame").grid(row=0, column=0)
The geometry manager methods (pack, grid, place) return None, so self.frame1 is evaluating to None
To fix this, declare your frame and then put it on the grid separately:
self.frame1 = ttk.Frame(parent, style="Frame1.TFrame")
self.frame1.grid(row=0, column=0)
That said, I put together a quick boilerplate app to test this and it seemed to work without issues...
"""Tkinter Boilerplate App Example"""
import tkinter as tk
from tkinter import ttk
class App(tk.Tk):
def __init__(self):
super.__init__()
self.geometry('200x200')
self.title('Stylish')
self.frame = ttk.Frame(self, style='Frame1.TFrame')
self.frame.pack(expand=True, fill=tk.BOTH) # fill available space
self.style = ttk.Style()
# note: 'foreground' doesn't appear to have any effect on a Frame
self.style.configure('Frame1.TFrame', background='pink', foreground='red')
if __name__ == '__main__':
app = App()
app.mainloop()

Why do the buttons not appear in the tkinter window?

I am currently trying to learn tkinter. I do not understand why the buttons I defined do not appear in this code:
from tkinter import *
class Window(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.master = master
button1 = Button(self, text="Exit", width=12, command=self.clickButton1)
button1.grid(row=0)
button2 = Button(self, text="Test", width=12, command=self.clickButton2)
button2.grid(row=1)
def clickButton1(self):
exit()
def clickButton2(self):
print("Nice")
root = Tk()
app = Window(root)
root.title("Tkinter window")
root.mainloop()
When I don't use a class it works. Like this for example:
from tkinter import *
root = Tk()
button1 = Button(root, text="Works!!!")
button1.grid(row=0)
button2 = Button(root, text="Also works!!!")
button2.grid(row=1)
root.mainloop()
ยดยดยด
The reason is that the class creates a frame, and then puts widgets inside the frame. However, you never add the frame to the window so the widgets inside the frame will be invisible.
You need to make sure and call pack, grid, or place on the instance of Window, just like you do with any other widget.
app = Window(root)
app.pack(fill="both", expand=True)

Tkinter Bugs wrt adding mulitple buttons to menu bar

Attempting to create a menu box but I am having trouble adding multiple buttons, there is only a "Quit" button visible when I run the code, please assist xx
class Menu(Frame):
def __init__(self, master = None):
Frame.__init__(self, master)
self.master = master
self.init_menu()
def init_menu(self):
self.master.title("DUNGEON MENU")
self.pack(expand = True, fill=BOTH)
quitB = Button(self, text = "Quit", fg = "red", command = self.client_exit)
quitB.grid(row = 0, column = 3, padx = 120)
def client_exit(self):
exit()
lootB = Button(self, text = "Loot", command = None)
lootB.grid(row = 1, column = 3, padx = 120)
root = Tk()
root.geometry("300x300")
app = Menu(root)
root.mainloop()
button.pack()```
I have created a working version from your code. You can find my finding in the below code as comments.
I am not totally sure what your expectation about your code. Now the "Quit" and "Loot" buttons are visible on the Frame and if you click to "Quit" button, the program will be end (Loot button does nothing).
Code:
from tkinter import Frame, BOTH, Button, Tk
class Menu(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.master = master
self.init_menu()
# You have to call the "client_exit" method to rendering the "Loot" button to Frame.
self.client_exit()
def init_menu(self):
self.master.title("DUNGEON MENU")
self.pack(expand=True, fill=BOTH)
# Destroy the master if you click to the "Quit" button.
quitB = Button(self, text="Quit", fg="red", command=lambda: self.master.destroy())
quitB.grid(row=0, column=0, padx=120)
def client_exit(self):
# exit() # This exit is not needed because it breaks the program running.
# You can define the call-back of button in "command" parameter of Button object.
lootB = Button(self, text="Loot", command=None)
lootB.grid(row=1, column=0, padx=120)
root = Tk()
root.geometry("300x300")
app = Menu(root)
root.mainloop()
# button.pack() # It does not have effect. You cannot define widgets after "mainloop"
Output:
>>> python3 test.py

Problem with tkinter and urllib for checking websites

I am trying to create an application that will allow you to put in multiple websites and check if they are down. When I run the code the window opens and everything works fine until i click search. Then i get the following error
AttributeError: 'Window' object has no attribute 'text_entry'
Any help would be greatly appreciated
#Import everything from tkinter
from tkinter import *
import urllib.request
#Main window
class Window(Frame):
#Master Widget
def __init__(self, master = None):
Frame.__init__(self, master)
self.master = master
self.init_window()
#Creation of init_window
def init_window(self):
# changing the title of our master widget
self.master.title("GUI")
# allowing the widget to take the full space of the root window
self.pack(fill=BOTH, expand=1)
#Menu
menu = Menu(self.master)
self.master.config(menu=menu)
#File Menu option
file = Menu(menu)
file.add_command(label="Exit", command=self.client_exit)
menu.add_cascade(label="File", menu=file)
#Text Box
text_entry = Entry(self, width=20, bg="white")
text_entry.place(x=0, y=0)
#Submit button
searchButton = Button(self, text='SUBMIT', width=6,
command=self.search)
searchButton.place(x=200, y=30)
#Output Box
output = Text(self, width=20, height=1, bg="white")
output.place(x=0, y=50)
def search(self):
entered_text = self.text_entry.get()
output.delete(0.0, END)
definition=(int(urllib.request.urlopen(entered_text).getcode()))
output.insert(END, definition)
root = Tk()
#Size of the window
root.geometry("400x300")
#Window instance
app = Window(root)
#Show and mainloop
root.mainloop()
You haven't put text_entry on the self object and you can't access it in search function.
#Text Box
self.text_entry = Entry(self, width=20, bg="white")
self.text_entry.place(x=0, y=0)

Categories