1
`from tkinter import *
pencere = Tk()
başlık = pencere.title("deneme2")
etiket = Label(text="")
etiket.pack()

def göster(event):
    etiket["text"] = "%s seçildi."%liste.get(ACTIVE)
    etiket.pack()
liste = Listbox()
liste.insert(1, "İstanbul")
liste.insert(2, "Ankara")
liste.insert(3, "İzmir")
liste.insert(4, "İzmit")
liste.insert(5, "Antalya")
liste.insert(6, "Bursa")
liste.pack()

liste.bind("<Button-1>",göster)
mainloop()`

here is the problem! I follow an online course and couldn't figure out why it would show the wrong text. I choose İzmir it says İstanbul, I choose Ankara it says İstanbul, I choose İstanbul it says Ankara, other ones are like this too.

Claudio
  • 7,474
  • 3
  • 18
  • 48
  • Research the `<>` event. For more information about the order that events are processed see https://stackoverflow.com/questions/11541262/basic-query-regarding-bindtags-in-tkinter/11542200#11542200. That link talks about keypresses in an entry widget, but the same concept applies to clicks in a listbox. – Bryan Oakley Jun 25 '22 at 23:52

2 Answers2

0

Your code is working. Just double click it. You don't need etiket.pack() inside the göster function. I had to rearrange our code to make it more readable. Just double click it. I also added widget for Label and Listbox.

from tkinter import *


pencere = Tk()
başlık = pencere.title("deneme2")
 

def göster(event):
    etiket.config(text = "%s seçildi."%liste.get(ACTIVE))

etiket = Label(pencere)
etiket.pack()

liste = Listbox(pencere)
liste.insert(0, "İstanbul")
liste.insert(1, "Ankara")
liste.insert(2, "İzmir")
liste.insert(3, "İzmit")
liste.insert(4, "Antalya")
liste.insert(5, "Bursa")
 
liste.pack()
etiket.pack()

liste.bind("<Button-1>",göster)
 
mainloop()
toyota Supra
  • 3,181
  • 4
  • 15
  • 19
  • By the way, I start with index 0 rather than 1. – toyota Supra Jun 26 '22 at 02:29
  • 1
    The index has an impact on effect of `liste.insert(N, "Text")` only when in the `liste` are more elements as the value of the index. Then the item will be inserted into the `liste` before the item with the index N in the `liste` starting counting with 0. – Claudio Jun 26 '22 at 12:24
0

Let's first focus on the question

Why does the listbox not respond with the just by the click selected item, but with the last clicked one?

To change the in the listbox selected item you have to perform a click on that item. In the event-driven mechanism of tkinter the listbox will then be 'informed' about the mouse click and 'react' to it changing its value.

When you capture the mouse click by binding it to your function the function will be notified about the mouseclick before the listbox receive it. The listbox does at the time of the click not yet 'know' that it will become clicked next as the click is first processed by your function and only after passed to the listbox.

So the 'poor' listbox asked in the function about its current selected value responds with the last one clicked and from listbox perspective also current value.

On the very first click when no item is yet selected if asked using ACTIVE the listbox responds with its first value and if asked with listbox.curselection() it returns no value at all.

Checking the state of the listbox with listbox.get(ACTIVE) behaves different from checking its state with listbox.get(listbox.curselection()) where the latter responds as intuitively expected.

Please be aware that the explanation above is simplified and things are often not straightforward in event-driven programming environment, but simple explanation helps to understand the importance of doing things the right way to minimize the chances that sometimes something will go wrong.

The code you provided has two issues at the same time and you have to resolve both to get the by you expected result.

First issue is that you bind <Button-1> (i.e. the mouse click) instead of capturing the <<ListboxSelect>> event and the second issue is, that you should ask the listbox about its current selected item using listbox.get(listbox.curselection()) instead of listbox.get(ACTIVE).

The code below demonstrates all four cases showing that in only one case things work out as expected. Let's summarize all of what was said above in one simple statement:

You should use <<ListboxSelect>> event for the binding and listbox.get(listbox.curselection()) for the value of the selected item in the listbox.

from tkinter import *
list_CASE = ['']
list_CASE.append("<Button-1>(Mouse Click), liste.get(ACTIVE)")
list_CASE.append("<Button-1>(Mouse Click), liste.get(liste.curselection())")
list_CASE.append("<<ListboxSelect>>, liste.get(ACTIVE)")
list_CASE.append("<<ListboxSelect>>, liste.get(liste.curselection())")

def göster(event):
    # global indx, etiket, liste
    if indx in [1,3]: 
        etiket["text"] = "%s seçildi."%liste.get(ACTIVE)
    if indx in [2,4]: 
        etiket["text"] = "%s seçildi."%liste.get(liste.curselection())

for indx, CASE in enumerate(list_CASE): 
    if indx == 0 : continue
    pencere = Tk()
    pencere.geometry('700x400+300+300')
    pencere.title(CASE)
    # başlık = pencere.title("deneme2")
    etiket = Label(text="", font=(16)); etiket.pack()

    liste = Listbox(selectmode='browse', font=(16))
    liste.insert(1, "İstanbul")
    liste.insert(2, "Ankara")
    liste.insert(3, "İzmir")
    liste.insert(4, "İzmit")
    liste.insert(5, "Antalya")
    liste.insert(6, "Bursa")
    liste.pack()
    
    if indx in [1,2]: liste.bind("<Button-1>"       , göster)
    if indx in [3,4]: liste.bind("<<ListboxSelect>>", göster) 

    mainloop()
Claudio
  • 7,474
  • 3
  • 18
  • 48
  • It showing wrong text. – toyota Supra Jun 26 '22 at 11:22
  • 1
    Yes, the first three cases are showing the wrong text. The fourth version (see TITLE of the window for description of case) is showing the right text (this with `<>` event for the binding and `listbox.get(listbox.curselection())` for getting the text. ). Close the first window and a second will pop-up ... then the third and then the fourth. – Claudio Jun 26 '22 at 11:54