У меня есть код ниже, который создает простой список и позволяет пользователям выбирать элемент и перемещать их вверх или вниз по списку, тем самым переупорядочивая список.
Проблема, которую я имею прямо сейчас, - это каждый раз, когда я нажимаю "двигаться вверх" или "перемещаться вниз", действие выполняется правильно, но курсор больше не остается выбранным. Я должен снова выбрать элемент, чтобы снова выполнить функцию.
Я попытался настроить exportselection = False при настройке списка, но это не сработало.
import tkinter as tk
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.wm_title("Animals")
self._frame = None
class AnimalPage(tk.Frame):
def __init__(self, master, controller):
tk.Frame.__init__(self, master)
self.master = master
self.controller = controller
self.config(relief='sunken', borderwidth=2)
self.pack(fill = "both", expand = False)
tk.Label(self, text="This is the Animal Configuration Page").pack()
self.animalList = ['Cat', 'Dog', 'Bear', 'Dolphin', 'Kangaroo']
self.animalString = tk.StringVar(value=self.animalList)
self.animalBox = tk.Listbox(self, listvariable=self.animalString,
height=25, width=50, borderwidth=2)
self.animalBox.pack()
moveUpButton = tk.Button(self, text="Move Up", command=lambda: self.moveup())
moveUpButton.pack()
moveDownButton = tk.Button(self, text="Move Down", command=lambda: self.movedown())
moveDownButton.pack()
def moveup(self, *args):
try:
self.idxs = self.animalBox.curselection()
if not self.idxs:
return
for pos in self.idxs:
if pos==0:
continue
text=self.animalBox.get(pos)
self.animalBox.delete(pos)
self.animalBox.insert(pos-1, text)
self.animalList.pop(pos)
self.animalList.insert(pos-1, text)
except:
pass
def movedown(self, *args):
try:
self.idxs = self.animalBox.curselection()
if not self.idxs:
return
for pos in self.idxs:
if pos==0:
continue
text=self.animalBox.get(pos)
self.animalBox.delete(pos)
self.animalBox.insert(pos+1, text)
self.animalList.pop(pos)
self.animalList.insert(pos+1, text)
except:
pass
if __name__ == "__main__":
app = SampleApp()
newFrame = AnimalPage(app, app)
app.geometry("1200x700")
app.mainloop()
Просто используйте selection_set для сохранения выбранного элемента, например:
def moveup(self, *args):
try:
self.idxs = self.animalBox.curselection()
if not self.idxs:
return
for pos in self.idxs:
if pos==0:
continue
text=self.animalBox.get(pos)
self.animalBox.delete(pos)
self.animalBox.insert(pos-1, text)
self.animalList.pop(pos)
self.animalList.insert(pos-1, text)
self.animalBox.selection_set(pos-1)
except:
pass
И аналогичным образом для movown.
Чтобы выбор был выбран, вы должны фактически выбрать правильный индекс в коде, так как он находится в новом месте. К счастью, box select_set (i) делает это. вы сделали бы это следующим образом:
def moveup(self, *args):
try:
self.idxs = self.animalBox.curselection()
if not self.idxs:
return
for pos in self.idxs:
if pos==0:
continue
text=self.animalBox.get(pos)
self.animalBox.delete(pos)
self.animalBox.insert(pos-1, text)
self.animalList.pop(pos)
self.animalList.insert(pos-1, text)
self.animalBox.select_set(pos-1)
except:
pass
Исправленный код для motionown:
def movedown(self, *args):
try:
self.idxs = self.animalBox.curselection()
if not self.idxs:
return
for pos in self.idxs:
# Are we at the bottom of the list?
if pos == len(self.animalList)-1:
continue
text=self.animalBox.get(pos)
self.animalBox.delete(pos)
self.animalBox.insert(pos+1, text)
self.animalList.pop(pos)
self.animalList.insert(pos+1, text)
self.animalBox.selection_set(pos + 1)
except:
pass