1

In my program, I have a frame (in customtkinter), this frame updates to display new information each time a button is pressed. The issue is that some of the text is glitched after pressing more than 1-2 buttons to display different things. Not sure what the issue is or how to solve it.

Heres my code:

    def linepick(linechoice):
        
        if linechoice == "Waterloo & City":
            linechoice = "waterloo-city"

        else:
            None
           
        if linechoice == "Hammersmith & City":
            linechoice = "hammersmith-city"

        else:
            None

        endpoint = f"https://api.tfl.gov.uk/Line/{linechoice}/Status"
        response = requests.get(endpoint)
        
        if response.status_code == 200:
           
           data = response.json()

           if len(data) > 0 and "lineStatuses" in data[0]:
               linedata1 = data[0]["lineStatuses"][0]
               
               if linechoice == "waterloo-city":
                linechoice = "Waterloo & City"

               else:
                None
           
               if linechoice == "hammersmith-city":
                linechoice = "Hammersmith & City"

               else:
                None

               label1 = ct.CTkLabel(frame, text=f'{linechoice} line:{linedata1["statusSeverityDescription"]}', font=("Arial", 16))
               label1.place(x=0, y=30)
        
        elif response.status_code == 300:

            redirection = response.headers["location"]
            rerequest = requests.get(redirection)
            rerequestdata = rerequest.json()

            if len(rerequestdata) > 0 and "lineStatuses" in rerequestdata[0]:
                linedata2 = rerequestdata[0]["lineStauses"][0]

                if linechoice == "waterloo-city":
                 linechoice = "Waterloo & City"

                else:
                 None
           
                if linechoice == "hammersmith-city":
                  linechoice = "Hammersmith & City"

                else:
                 None

                label2 = ct.CTkLabel(frame, text=f'{linechoice} line:{linedata2["statusSeverityDescription"]}', font=("Arial", 16))
                label2.place(x=0, y=30)

        else:
           label3 = ct.CTkLabel(frame, text="Status line not reached, try again later.", font=("Arial", 16))
           label3.place(x=0, y=30)
        
    
    #Creating an optionmenu---------------------------------------
    stationmenu = ct.CTkOptionMenu(
        issuewindow, 
        values=["Bakerloo","Waterloo & City","Central","Circle","District","Hammersmith & City","Jubilee","Metropolitan","Northern","Piccadilly","Victoria"], 
        font=("Arial", 20), 
        corner_radius=10,
        fg_color="#0C56FF",
        command=linepick)
    stationmenu.place(x=35, y=40)

Thats the function which updates the text and thats the option menu im using

The frame itself is just a simple frame in tkinter.

Heres a picture of the glitching:

Picture of the glitching.

I think one way of solving it would be to make the frame update itself each time a button is pressed but i'm not sure how to really implement that in here. (my programming skills are very basic)

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
BigJ
  • 23
  • 4
  • 3
    You aren't actually updating anything, you're just layering a new Label on top of the old ones. Whenever the new text is shorter than the previous text, you'll be able to see parts of the previous text. A better approach would be to create a single Label at the very start, and just change its text as needed. – jasonharper May 02 '23 at 20:56
  • Ah that makes a lot of sense, thank you. – BigJ May 03 '23 at 13:08

1 Answers1

1

The problem is you are creating new labels without deleting the old ones. The way it is set up now also does not have a reference to the old labels to delete them.

The easiest thing to do to fix this is to create the label outside the function and just update the label's text instead of creating a new label. to do this you can just create your label like when creating your stationmenu you can see an example of this below...

# create optionmenu
stationmenu = ct.CTkOptionMenu(
    issuewindow, 
    values=["Bakerloo","Waterloo & City","Central","Circle","District","Hammersmith & City","Jubilee","Metropolitan","Northern","Piccadilly","Victoria"], 
    font=("Arial", 20), 
    corner_radius=10,
    fg_color="#0C56FF",
    command=linepick
)
stationmenu.place(x=35, y=40)

# create optionmenu label
stationmenu_label = ct.CTkLabel(frame, text="", font=("Arial", 16))
stationmenu_label.place(x=0, y=30)

You might just need to specify the starting text of the label. Then when an option is selected in your stationmenu then you just change the text of the label and update the window. A cleaned-up example of this is shown below.

def linepick(linechoice):
    url_encoded_linechoice = linechoice
    
    if url_encoded_linechoice == "Waterloo & City":
        url_encoded_linechoice = "waterloo-city"  
    elif url_encoded_linechoice == "Hammersmith & City":
        url_encoded_linechoice = "hammersmith-city"

    endpoint = f"https://api.tfl.gov.uk/Line/{url_encoded_linechoice}/Status"
    response = requests.get(endpoint)
    data = None
    text = "" #specify default text if 'lineStatuses' is not in the data
    
    if response.status_code == 200:
       data = response.json()

       if len(data) > 0 and "lineStatuses" in data[0]:
           linedata = data[0]["lineStatuses"][0]
           text = f'{linechoice} line:{linedata["statusSeverityDescription"]}'
    
    elif response.status_code == 300:
        redirection = response.headers["location"]
        rerequest = requests.get(redirection)
        data = rerequest.json()
        
        if len(data) > 0 and "lineStatuses" in data[0]:
            linedata = data[0]["lineStauses"][0]
            text= f'{linechoice} line:{linedata["statusSeverityDescription"]}' 

    else:
       text = "Status line not reached, try again later."
    
    stationmenu_label["text"] = text # or instead you can use stationmenu_label.configure(text = text)
    # update your window using your_window_name.update()
    # update your window's idletasks using your_window_name.update_idletasks() 

This code was not tested so it may need slight tweaking to fit your needs, but it should fix the problems you were having with the label.

alantbarlow
  • 138
  • 6
  • Makes perfect sense, thank you. Will go and fix the issue when I get home. – BigJ May 03 '23 at 13:08
  • Fixed now. Appreciate it. – BigJ May 03 '23 at 15:46
  • @BigJ, I'm glad to hear. if you found my code to be helpful can you please upvote it, and if it solved your problem, can you please mark it as the correct answer. – alantbarlow May 03 '23 at 15:49
  • 1
    Need 15 comments to upvote which I don’t have but I believe I have marked it as the correct answer. – BigJ May 04 '23 at 16:59