Home > Back-end >  Why isn't my tkinter program working? I can't find errors
Why isn't my tkinter program working? I can't find errors

Time:06-14

My Tkiner program isn't working and i don't know why. The program gotta change image of city when user clicks on the buttons. Also the night mode checkbutton must change the image from day to night. None of those do not work. I attached the screen of my output. Thanks everyone for helping!

q1 = """Paris Paris Paris Paris Paris Paris Paris
Paris Paris Paris Paris Paris Paris Paris Paris
Paris Paris Paris Paris Paris Paris Paris Paris"""
q2 = """Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1
Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1
Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 """
w1 = """ london london london london london london
london london london london london london london
london"""
w2 = """Paris Paris Paris Paris Paris Paris Paris
Paris Paris Paris Paris Paris Paris Paris Paris
Paris Paris Paris Paris Paris Paris Paris Paris"""
e1 = """Paris Paris Paris Paris Paris Paris Paris
Paris Paris Paris Paris Paris Paris Paris Paris
Paris Paris Paris Paris Paris Paris Paris Paris"""
e2 = """Paris Paris Paris Paris Paris Paris Paris
Paris Paris Paris Paris Paris Paris Paris Paris
Paris Paris Paris Paris Paris Paris Paris Paris"""

class City():
    """docstring for City"""
    def __init__(self, text, text_night, image, image_night):
        self.text = text
        self.text_night = text_night
        self.image = image
        self.image_night = image_night

def Paris():
    if result.get() == 1:
        text.configure(text=str(Paris.text_night))
        label.configure(image=Paris.image_night)
    else:
        print("123")


Paris = City(q1, q2, "london_day.gif", "london_night.gif")
London = City(w1, w2, "london_day.gif", "london_night.gif")
Berlin = City(e1, e2, "london_day.gif", "london_night.gif")

from tkinter import *
root = Tk()
root.title("Trips")
root.geometry("750x400")
frame = Frame(root, width = 1, height=4)


knopka1=Button(master=frame, text="Paris", command=Paris)
knopka1.pack(padx=5, pady=5)
knopka2=Button(master=frame, text="London")
knopka2.pack(padx=5, pady=5)
knopka3=Button(master=frame, text="Berlin")
knopka3.pack(padx=5, pady=5)

result = IntVar()
praporets = Checkbutton(master=frame, text = "Night mode", variable = result ,onvalue = 1, offvalue = 0, height=5, width = 20)
praporets.pack(padx=5, pady=5)
frame.pack(side=LEFT)

img = PhotoImage(file = Paris.image)
image1 = img.subsample(2, 2)
label = Label(root, image=image1).pack(side= LEFT)
text = Label(root, text=Paris.text)
text.pack(side=LEFT)

root.mainloop()

[enter image description here][1]


  [1]: https://i.stack.imgur.com/UDqIO.png

CodePudding user response:

There is a bit to unpack here.

First, the pack method returns None, so when you do:

label = Label(root, image=image1).pack(side= LEFT)

label is basically None so changing its image won't work.

Secondly, instead of writing a function for Paris why don't you write a generic function that will take a City as argument? You can then assign this function as command for your buttons using a lambda function.

Finally, as mentionned in this answer image1 would be garbaged collected at the end of your function, so you should specify that you're using the already declared variable inside your function with global. (the better solution would be to create your window as a class, and set self.image1)

q1 = """Paris Paris Paris Paris Paris Paris Paris
Paris Paris Paris Paris Paris Paris Paris Paris
Paris Paris Paris Paris Paris Paris Paris Paris"""
q2 = """Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1
Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1
Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 """
w1 = """ london london london london london london
london london london london london london london
london"""
w2 = """Paris Paris Paris Paris Paris Paris Paris
Paris Paris Paris Paris Paris Paris Paris Paris
Paris Paris Paris Paris Paris Paris Paris Paris"""
e1 = """Paris Paris Paris Paris Paris Paris Paris
Paris Paris Paris Paris Paris Paris Paris Paris
Paris Paris Paris Paris Paris Paris Paris Paris"""
e2 = """Paris Paris Paris Paris Paris Paris Paris
Paris Paris Paris Paris Paris Paris Paris Paris
Paris Paris Paris Paris Paris Paris Paris Paris"""

class City():
    """docstring for City"""
    def __init__(self, text, text_night, image, image_night):
        self.text = text
        self.text_night = text_night
        self.image = image
        self.image_night = image_night


def set_city_pic(city: City):
    global image1
    if night_mode.get():
        im = PhotoImage(file=city.image_night)
        text.configure(text=str(city.text_night))
    else:
        im = PhotoImage(file=city.image)
        text.configure(text=str(city.text))

    image1 = im.subsample(2, 2)
    label.configure(image=image1)

Paris = City(q1, q2, "paris_day.png", "paris_night.png")
London = City(w1, w2, "london_day.png", "london_night.png")
Berlin = City(e1, e2, "berlin_day.png", "berlin_night.png")

from tkinter import *

root = Tk()
root.title("Trips")
root.geometry("750x400")
frame = Frame(root, width = 1, height=4)


knopka1=Button(master=frame, text="Paris", command=lambda: set_city_pic(Paris))
knopka1.pack(padx=5, pady=5)
knopka2=Button(master=frame, text="London", command=lambda: set_city_pic(London))
knopka2.pack(padx=5, pady=5)
knopka3=Button(master=frame, text="Berlin", command=lambda: set_city_pic(Berlin))
knopka3.pack(padx=5, pady=5)

night_mode = IntVar()
praporets = Checkbutton(master=frame, text = "Night mode", variable = night_mode, onvalue = 1, offvalue = 0, height=5, width = 20)
praporets.pack(padx=5, pady=5)
frame.pack(side=LEFT)

im = PhotoImage(file=Paris.image)
image1 = im.subsample(2, 2)
label = Label(root,  image=image1)
label.pack(side= LEFT)
text = Label(root)
text.pack(side=LEFT)

root.mainloop()

CodePudding user response:

I think the problem is your name convention. You create a function with name "Paris" but then overwrite the variable with a class that you create. Then, when you pass "Paris" as a command for the button, the button tries to execute "Paris", but Paris is an object which can't be executed. That's also the reason why you don't get an error.

def change(self):
     if result.get() == 1:
         self.text.configure(text=str(self.text_night))
         self.label.configure(image=self.image_night)
     else:
          print('123')

Also, to access "text" like you want to do in your now called function "changeParis", you'd need to make "change" a method of "City". Thats, why you need to pass "self" as an argument.

Last but not least, you need to pass your references of your labels etc. into "City" otherwise, you can't access them.

That's my final code:

q1 = """
Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris""" q2 = """Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 Paris1 """ w1 = """ london london london london london london london london london london london london london london""" w2 = """Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris""" e1 = """Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris""" e2 = """Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris Paris
"""
    
class City():
    """docstring for City"""
    def __init__(self, text, text_night, image, image_night, label, text):
        self.text = text
        self.text_night = text_night
        self.image = image
        self.image_night = image_night
        self.label = label
        self.text = text

    def change(self):
        if result.get() == 1:
            self.text.configure(text=str(self.text_night))
            self.label.configure(image=self.image_night)
        else:
            print("123")
    
from tkinter import * root = Tk() root.title("Trips") root.geometry("750x400") frame = Frame(root, width = 1, height=4)

img = PhotoImage(file = Paris.image) image1 = img.subsample(2, 2) label = Label(root, image=image1).pack(side= LEFT) text = Label(root, text=Paris.text) text.pack(side=LEFT)
    
Paris = City(q1, q2, "london_day.gif", "london_night.gif", label, text) 
London = City(w1, w2, "london_day.gif", "london_night.gif", label, text) 
Berlin = City(e1, e2, "london_day.gif", "london_night.gif", label, text)
    
knopka1=Button(master=frame, text="Paris", command=Paris.change) knopka1.pack(padx=5, pady=5) 
knopka2=Button(master=frame, text="London") 
knopka2.pack(padx=5, pady=5) 
knopka3=Button(master=frame, text="Berlin") 
knopka3.pack(padx=5, pady=5)
    
    result = IntVar() 
praporets = Checkbutton(master=frame, text = "Night mode", variable = result ,onvalue = 1, offvalue = 0, height=5, width = 20) praporets.pack(padx=5, pady=5) 
frame.pack(side=LEFT)
    
root.mainloop()

I tried my best, but couldn't test it. Please be aware of this. I hope I could help you!

  • Related