从列表框和列表中删除选定的项目 [英] Removing selected items from the listbox and from the list

查看:86
本文介绍了从列表框和列表中删除选定的项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于我最近切换到Linux,所以我有一个用C#编写的应用程序,需要将其转换为Python.这是一个简单的GUI应用程序,用于在学习新语言时管理未知单词.但是,我需要 remove_item()函数,为此我还需要 find_word()函数.

I have an application written in C# that needs to be converted to Python, since I have recently switched to Linux. It's a simple GUI application to manage unknown words while learning a new language. Nevertheless, I need remove_item() function for which I also need find_word() function.

在C#中,我将创建以下两种方法:

In C#, I would create two following methods:

void Remove()
{
    Word word = new Word();
    try { word = FindWord(listView1.SelectedItems[0].Text); }
    catch { return; }
    if (listView1.SelectedItems.Count > 0)
    {
        try
        {
            foreach (ListViewItem eachItem in listView1.SelectedItems)
            {
                words.RemoveAll(x => x.WordOrPhrase == eachItem.Text);
                listView1.Items[listView1.Items.Count - 1].Selected = true;
                listView1.Items.Remove(eachItem);
            }
        }
        catch { }
        ClearAll();
        ReadOnlyON();
    }
    else
    {
        MessageBox.Show("You have not selected any words!", "Notification", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    ReadOnlyOFF();
    WordCount();
    Sync();
}

private Word FindWord(string word)
{
    return words.Find(x => x.WordOrPhrase == word);
}

...但是在Python方面,我还是一个新手,因此,我们将不胜感激.这是我到目前为止的内容:

...but I'm still a newbie when it comes to Python, so any help would be appreciated. Here is what I have so far:

涉及FindWord()方法时,可以将其重写如下:

When it comes to the FindWord() method, it could be rewritten as following:

def FindWord(word):
    for x in words:
        if x.WordOrPhrase == word:
            return x

def FindWord(word):
    return next((x for x in words if x.WordOrPhrase == word), None)

def FindWord(word):
    return next(filter(lambda x: x.WordOrPhrase == word, words), None)

...但是我正在努力重写Remove()方法.这是一种方法:

...but I'm struggling to rewrite Remove() method. Here is one way:

def remove_item(self):
    word = self.listBox.get(ACTIVE)
    new_word_list = []  # initialize empty list
    delete_idxs = []
    for idx, item in enumerate(self.words):
        if item.wordorphrase == word:
            delete_idxs.append(idx)
        else:
            new_word_list.append(item)
    self.words = new_word_list  # overwrite the old word_list with the new one
    for idx in reversed(delete_idxs):
        self.listBox.delete(idx)

...我最想将C#方法转换为Python.这是我到目前为止的内容:

...what I would like most is converting my C# method to Python. Here is what I have so far:

def remove_item(self):

    word = Word()

    try:
        word = find_word(self.listBox.curselection())
    except:
        return

    if self.listBox.len(curselection()) > 0:
        try:
            for item in self.listBox.curselection():
                self.words.remove(lambda x: x.wordorphrase == item.text)
                # listView1.Items[listView1.Items.Count - 1].Selected = true;
                self.listBox.remove(item)
        except:
            pass
        self.clear_all()

    else:
        pass
        # show messagebox

我不知道如何访问:

  • listView1.SelectedItems[0].Text
  • listView1.SelectedItems.Count > 0
  • listView1.SelectedItems
  • listView1.Items[listView1.Items.Count - 1].Selected
  • listView1.SelectedItems[0].Text
  • listView1.SelectedItems.Count > 0
  • listView1.SelectedItems
  • listView1.Items[listView1.Items.Count - 1].Selected

这是我到目前为止所做的:

Here is what I have done so far:

# Vocabulary.py
# GUI program to manage unknown words

from tkinter import *
from tkinter import ttk
from tkinter import messagebox
import xml.etree.ElementTree as ET
import os


class Word:

    def __init__(self, wordorphrase, explanation, translation, example):
        self.wordorphrase = wordorphrase
        self.explanation = explanation
        self.example = example
        self.translation = translation

class Vocabulary(Frame):

    def __init__(self, master):
        Frame.__init__(self, master)
        self.master = master
        self.master.resizable(width = False, height = False)
        self.master.title("Vocabulary")
        self.create_widgets()
        self.words = []
        self.load_words()

    def on_closing(self):

        self.save_all()

        if messagebox.askokcancel("Quit", "Do you want to quit?"):
            self.master.destroy()

    def create_widgets(self):

        self.buttons_frame = Frame(self.master)
        self.buttons_frame.grid(row = 10, sticky = W)

        self.search_frame = Frame(self.master)
        self.search_frame.grid(row = 1, sticky = W, columnspan = 2)

        self.comboBox = ttk.Combobox(self.search_frame,
                                     width = 3)
        self.comboBox.grid(row = 0, column = 14, sticky = W)
        self.comboBox['values'] = ( 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' )

        self.btn_Add = Button(self.buttons_frame,
                              text = 'Add',
                              command = self.add_item)
        self.btn_Add.grid(row = 0, sticky = W)

        self.btn_Remove = Button(self.buttons_frame,
                                 text = 'Remove',
                                 command = self.remove_item)

        self.btn_Remove.grid(row = 0, column = 1, sticky = W)

        self.btn_Edit = Button(self.buttons_frame,
                               text = 'Edit',
                               command = self.edit_item)
        self.btn_Edit.grid(row = 0, column = 2, sticky = W)

        self.btn_Save = Button(self.buttons_frame,
                               text = 'Save',
                               command = self.save_item)
        self.btn_Save.grid(row = 0, column = 3, sticky = W)

        self.btn_Refresh = Button(self.buttons_frame,
                                  text = 'Refresh',
                                  command = self.refresh_all)
        self.btn_Refresh.grid(row = 0, column = 4, sticky = W)

        self.lblSearch = Label(self.search_frame, text = 'SEARCH: ')
        self.lblSearch.grid(row = 0, column = 5, sticky = W)

        self.txt_Search = Text(self.search_frame,
                               height = 1,
                               width = 70)
        self.txt_Search.grid(row = 0, column = 6, columnspan = 3, sticky = W)

        self.lblWordsOrPhrases = Label(self.master, text = 'WORDS/PHRASES:')
        self.lblWordsOrPhrases.grid(row = 2, column = 0)

        self.lblWordOrPhrase = Label(self.master, text = 'Word or phrase:')
        self.lblWordOrPhrase.grid(row = 2, column = 1, sticky = W)

        self.listBox = Listbox(self.master,
                               selectmode='extended',
                               height = 34,
                               width = 38)
        self.listBox.grid(row = 3, column = 0, rowspan = 7, sticky = W)

        self.txt_WordOrPhrase = Text(self.master,
                                     height = 1,
                                     width = 40)
        self.txt_WordOrPhrase.grid(row = 3, column = 1, sticky = N)

        self.lblExplanation = Label(self.master, text = 'Explanation:')
        self.lblExplanation.grid(row = 4, column = 1, sticky = W)

        self.txt_Explanation = Text(self.master,
                                    height = 10,
                                    width = 40)
        self.txt_Explanation.grid(row = 5, column = 1, sticky = N)

        self.lblTranslation = Label(self.master, text = 'Translation:')
        self.lblTranslation.grid(row = 6, column = 1, sticky = W)

        self.txt_Translation = Text(self.master,
                                    height = 10,
                                    width = 40)
        self.txt_Translation.grid(row = 7, column = 1, sticky = N)

        self.lblExamples = Label(self.master, text = 'Example(s):')
        self.lblExamples.grid(row = 8, column = 1, sticky = W)

        self.txt_Example = Text(self.master,
                                height = 10,
                                width = 40)
        self.txt_Example.grid(row = 9, column = 1, sticky = S)

    def load_words(self):

        self.listBox.delete(0, END)
        self.words.clear()

        path = os.path.expanduser('~/Desktop')
        vocabulary = os.path.join(path, 'Vocabulary', 'Words.xml')

        if not os.path.exists(vocabulary):
            if not os.path.exists(os.path.dirname(vocabulary)):
                os.mkdir(os.path.dirname(vocabulary))
            doc = ET.Element('Words')
            tree = ET.ElementTree(doc)
            tree.write(vocabulary)
        else:
            tree = ET.ElementTree(file=vocabulary)

        for node in tree.findall('WordOrPhrase'):
            w = Word(node.find('Word').text, node.find('Explanation').text, node.find('Translation').text,
                     node.find('Examples').text)

            self.words.append(w)
            self.listBox.insert(END, w.wordorphrase)

    def save_all(self):

        path = os.path.expanduser('~/Desktop')
        vocabulary = os.path.join(path, 'Vocabulary', 'Words.xml')

        tree = ET.ElementTree(file=vocabulary)

        for xNode in tree.getroot().findall('WordOrPhrase'):
            tree.getroot().remove(xNode)

        for w in self.words:
            xTop = ET.Element('WordOrPhrase')
            xWord = ET.Element('Word')
            xExplanation = ET.Element('Explanation')
            xTranslation = ET.Element('Translation')
            xExamples = ET.Element('Examples')

            xWord.text = w.wordorphrase
            xExplanation.text = w.explanation
            xTranslation.text = w.translation
            xExamples.text = w.example

            xTop.append(xWord)
            xTop.append(xExplanation)
            xTop.append(xTranslation)
            xTop.append(xExamples)

            tree.getroot().append(xTop)

        tree.write(vocabulary)

    def add_item(self):

        w = Word(self.get_word(), self.get_explanation(), self.get_translation(), self.get_example())

        self.words.append(w)

        self.listBox.insert(END, w.wordorphrase)

        self.clear_all()

        self.save_all()

    def remove_item(self):

        word = Word()

        try:
            word = find_word(self.listBox.curselection())
        except:
            return

        if self.listBox.len(curselection()) > 0:
            try:
                for item in self.listBox.curselection():
                    self.words.remove(lambda x: x.wordorphrase == item.text)
                    # listView1.Items[listView1.Items.Count - 1].Selected = true;
                    self.listBox.remove(item)
            except:
                pass
            self.clear_all()

        else:
            pass
            # show messagebox

    def edit_item(self):
        pass

    def save_item(self):
        pass

    def clear_all(self):
        self.txt_WordOrPhrase.delete('1.0', END)
        self.txt_Explanation.delete('1.0', END)
        self.txt_Translation.delete('1.0', END)
        self.txt_Example.delete('1.0', END)

    def refresh_all(self):
        pass

    def get_word(self):
        return self.txt_WordOrPhrase.get('1.0', '1.0 lineend')

    def get_explanation(self):
        return self.txt_Explanation.get('1.0', '1.0 lineend')

    def get_translation(self):
        return self.txt_Translation.get('1.0', '1.0 lineend')

    def get_example(self):
        return self.txt_Example.get('1.0', '1.0 lineend')

    def find_word(word):
        for x in self.words:
            if x.wordorphrase == word:
                return x


def main():
    root = Tk()
    gui = Vocabulary(root)
    root.protocol('WM_DELETE_WINDOW', gui.on_closing)
    root.mainloop()

if __name__ == '__main__':
    main()

推荐答案

对于我的列表框,通常将模式设置为EXTENDED,以便用户可以选择一个或多个项目并立即将其全部删除.我是通过以下方法进行的:

For my listboxes, I generally have the mode set to EXTENDED so that users can select one or more items and remove all at once. I do so via the following method:

# Function with Tk.Listbox passed as arg
def remove_from(list_box):

    # Tuple of currently selected items in arg
    selected_items = list_box.curselection()

    # Initialize a 'repositioning' variable
    pos = 0

    for item in selected_items:
        # Set index of each item selected
        idx = int(item) - pos
        # Deletes only that index in the listbox
        list_box.delete(idx, idx)
        # Increments to account for shifts
        pos += 1

例如,假设我的列表框中有4个项目.然后,我选择第一项和第三项.通过致电list_box.curselection()我收到了以下信息:

For example, lets say in my listbox I had 4 items. I then select the first item and the third item. By calling list_box.curselection() I've received the following:

selected_items = (0, 2)

0是列表框中第一项的位置,2是第三项在位置中的位置.然后为元组中的每个项目建立索引.

Where 0 is the first item's position in the listbox, and 2 is the third item's position. Then for each item in my tuple, I establish its index.

详细介绍以下内容:

idx = 0 - 0
list_box.delete(0, 0)
pos = 1

所以现在我已删除位置0处的项目(例如第一个项目),并且列表框已移动!所以第二个现在是第一个,第三个是第二个,第四个是第三个.但是,我的元组不变,因为它是原始选择项的列表框中的位置.这是关键.接下来会发生什么:

So now I have deleted the item at position 0 (e.g. the first item) and my listbox has shifted! So the second is now the first, third is the second and fourth is the third. However, my tuple has not changed as it was the positions in the listbox of the original selection. This is key. What happens next is:

idx = 2 - 1
list_box.delete(1, 1)
pos = 2

由于列表框已移动,因此位置1现在对应于最初位于列表框第三位置的项目.对于n职位,这可以继续.

Since the listbox shifted, position 1 now corresponds to the item that was originally in the third position of the listbox. This can continue for n positions.

用于自删除单词

您可以尝试以下操作:

# Function with Tk.Listbox and self.words[] passed as args
def remove_from(list_box, list):

    # Tuple of currently selected items in arg
    selected_items = list_box.curselection()

    # List of Words already constructed
    word_list = list

    # Initialize a 'repositioning' variable
    pos = 0

    for item in selected_items:
        # Set index of each item selected
        idx = int(item) - pos
        # Deletes only that index in the listbox
        list_box.delete(idx, idx)
        # Gets the string value of the given index
        word = list_box.get(idx, idx)
        # Removes the word from the list
        if any(word in x for x in word_list):
            word_list.remove(word)
        # Increments to account for shifts
        pos += 1

这篇关于从列表框和列表中删除选定的项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆