Python/Tkinter: нежелательное взаимодействие между двумя виджетами

Ниже приведен наименьший полнофункциональный код tkinter, который я мог бы написать, чтобы продемонстрировать проблему, с которой я столкнулся в более крупном приложении. Этот код представляет два фрейма: левый содержит список, правый содержит прокручиваемый текстовый виджет. Когда пользователь выбирает элемент списка, содержимое этого элемента отображается в текстовом виджете. Если вы поместите курсор в текстовый виджет, все будет хорошо. Вы можете без проблем добавить больше текста и/или использовать клавишу удаления для удаления текста. Но если вы выбираете любой текст в текстовом виджете, вызывается функция «ListboxSelect» и выдает ошибку «IndexError: индекс кортежа вне диапазона». Это не имеет никакого смысла. Почему выбор текста в текстовом виджете вызывает функцию, которая явно привязана к виджету списка?

Python/Tkinter: нежелательное взаимодействие между двумя виджетами

import tkinter as tk
from tkinter import scrolledtext

root = tk.Tk()
root.geometry("400x200")

def listbox_selected(event):
    w = event.widget
    listbox_index = int(w.curselection()[0])
    right_text.delete(1.0,tk.END)
    right_text.insert(tk.END,left_listbox.get(listbox_index))

left_frame = tk.Frame(root,height=200,width=180,bg = "lightblue")
left_frame.place(x=15,y=2)

# left frame contains listbox
left_listbox = tk.Listbox(left_frame)
left_listbox.bind("<<ListboxSelect>>",listbox_selected)
left_listbox.place(x=5,y=5)
for index in range(5):
    left_listbox.insert(index,"This is item " + str(index))

right_frame = tk.Frame(root,height=200,width=180,bg = "lightyellow")
right_frame.place(x=200,y=5)

# right frame contains scrollable text widget
right_text = tk.scrolledtext.ScrolledText(right_frame,width=18,
                                                height=10)
right_text.place(x=5,y=5)

root.mainloop()
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
26
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это связано с тем, что при выборе текста внутри Text виджет отменяет выбор выбранного элемента в Listbox, что вызывает событие <<ListboxSelect>>.

Отмену выбора в Listbox можно отключить, установив exportselection=0:

left_listbox = tk.Listbox(left_frame, exportselection=0)

Другой способ — проверить, есть ли внутри listbox_selected() выбранный предмет:

def listbox_selected(event):
    w = event.widget
    selection = w.curselection()
    # check whether there is item selected
    if selection:
        listbox_index = int(selection[0])
        right_text.delete(1.0,tk.END)
        right_text.insert(tk.END,left_listbox.get(listbox_index))

Большое спасибо...много полезной информации. Итак, я предполагаю, что новое утверждение: если выбор: (верно) означает «если есть выбор конкретно в виджете списка?

fmex 22.03.2022 18:55

На самом деле, при экспериментировании комбинация обоих вариантов работает лучше всего. Если я использую только второе решение (при выборе:)... список становится невыбранным, когда текст выбран в списке. В обоих решениях (exportselection=0 и if selection:) список не становится невыбранным. А функции вырезания и вставки продолжают работать в текстовом виджете. Спасибо еще раз.

fmex 22.03.2022 19:02

@fmex Если это решит ваш вопрос, рассмотрите возможность принять его как ответ.

acw1668 31.03.2022 17:39

Где я могу принять это как ответ? Я не вижу такой опции нигде на этой странице, спасибо.

fmex 01.04.2022 18:08

Другие вопросы по теме