Skip to main content
 首页 » 编程设计

python之如何在不丢失选择的情况下在 Tkinter 的列表框中向上或向下移动项目

2025年05月04日12me-sa

我有下面的代码,它创建了一个简单的列表框,并允许用户选择项目并将它们向上或向下移动到列表中,从而重新排列列表。

我现在遇到的问题是每次按“上移”或“下移”时,操作都正确执行,但光标不再保持选中状态。我必须重新选择该项目才能再次执行该功能。

我尝试在设置列表框时配置 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 

对于下移也是如此。