staging.inyokaproject.org

python3 - ultimatelistctl Item entfernen

Status: Ungelöst | Ubuntu-Version: Kein Ubuntu
Antworten |

jb-alvarado

Anmeldungsdatum:
28. November 2012

Beiträge: 345

Hallo Allerseits,

ich habe hier ein Testprogramm:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import wx
from wx.lib.agw import ultimatelistctrl as ULC


class MainPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.run_list = []
        self.selected_obj = None

        self.dark_gray = wx.Colour(230, 230, 230)
        self.light_gray = wx.Colour(250, 250, 250)

        btnSizer = wx.BoxSizer(wx.HORIZONTAL)

        agwStyle = (
            ULC.ULC_HAS_VARIABLE_ROW_HEIGHT | wx.LC_REPORT | wx.LC_SINGLE_SEL)

        self.ul = ULC.UltimateListCtrl(
            self, agwStyle=agwStyle)

        runBtn = wx.Button(self, label="run")
        runBtn.Bind(wx.EVT_BUTTON, self.onRun)
        btnSizer.Add(runBtn, 0, wx.ALL, 5)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.ul, 1, wx.EXPAND | wx.ALL, 5)
        sizer.Add(btnSizer, 0, wx.CENTER | wx.ALL, 5)
        self.SetSizer(sizer)

        mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_FORMAT

        def gen_column_header(name, kind=0, mask=mask):
            info = ULC.UltimateListItem()
            info._mask = mask
            info._format = 0
            info._kind = kind
            info._text = name
            return info

        self.types = ['tv', 'dvd']

        self.ul.InsertColumnInfo(
            0, gen_column_header("Name"))
        self.ul.SetColumnWidth(0, 100)

        for i in range(len(self.types)):
            idx = i + 1
            self.ul.InsertColumnInfo(idx, gen_column_header(
                self.types[i], 1, mask | ULC.ULC_MASK_CHECK))
            self.ul.SetColumnWidth(idx, 100)

        self.Bind(ULC.EVT_LIST_COL_CHECKING, self.checkBoxHeader)
        self.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.OnRightClick)

        for i in range(5):
            self.ul.InsertStringItem(i, "name " + str(i))
            if i % 2:
                color = self.dark_gray
            else:
                color = self.light_gray
            self.ul.SetItemBackgroundColour(i, color)

            for j in range(len(self.types)):
                name = self.types[j]
                self.ul.SetStringItem(i, j + 1, "")
                self.checkBox = wx.CheckBox(
                    self.ul, wx.ID_ANY, "", wx.DefaultPosition,
                    wx.DefaultSize, 0, name=name)
                self.checkBox.SetBackgroundColour(color)
                self.ul.SetItemWindow(i, j + 1, self.checkBox, expand=True)
                self.run_list.append([self.checkBox, i, j + 1])

    def OnRightClick(self, event):
        self.selected_obj = event
        self.popupmenu = wx.Menu()
        self.popupmenu.Append(-1, "Delete")
        self.Bind(wx.EVT_MENU, self.onSelectContext)
        self.PopupMenu(self.popupmenu, event.GetPoint())
        self.popupmenu.Destroy()

    def onSelectContext(self, event):
        idx = self.selected_obj.GetIndex()
        self.selected_obj.EventObject.Select(idx, on=False)

        del_list = []

        for item in self.run_list:
            if item[1] == idx:
                del_list.append(item)

        for d in del_list:
            self.run_list.remove(d)

        self.selected_obj.EventObject.DeleteItem(idx)
        self.selected_obj = None
        del_list = []

    def onRun(self, event):
        comp_list = []
        for i in self.run_list:
            if i[0].IsChecked():
                n = i[0].GetName()
                comp_list.append([n, i[1]])
        print(comp_list)

    def checkBoxHeader(self, event):
        header_idx = event.m_col
        is_checked = event.EventObject.GetColumn(event.m_col)._checked

        for item in self.run_list:
            if item[2] == header_idx:
                if is_checked:
                    item[0].SetValue(False)
                else:
                    item[0].SetValue(True)


class MainFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="pyTable", size=(335, 235))
        MainPanel(self)
        self.Show()


if __name__ == "__main__":
    app = wx.App(False)
    frame = MainFrame()
    app.MainLoop()

Alles funktioniert auch soweit. Allerdings möchte ich über ein Rechtemaus-Klick-Menü Items entfernen können. Funktioniert auch theoretisch, wenn ich jedoch die letzte Row löschen möchte kommt die Fehlermeldung:

Traceback (most recent call last):
  File "C:\Python36\lib\site-packages\wx\lib\agw\ultimatelistctrl.py", line 7719, in OnMouse
    if not self.IsHighlighted(current):
  File "C:\Python36\lib\site-packages\wx\lib\agw\ultimatelistctrl.py", line 6879, in IsHighlighted
    ld = self.GetLine(line)
  File "C:\Python36\lib\site-packages\wx\lib\agw\ultimatelistctrl.py", line 6435, in GetLine
    return self._lines[n]
IndexError: list index out of range

Kennt Ihr eine Möglichkeit wie ich das beheben kann?

apt-ghetto

Anmeldungsdatum:
3. Juni 2014

Beiträge: 2943

So auf die Schnelle kannst du es beispielsweise so überprüfen:

1
2
3
4
if 0 <= n < len(items):
    items.remove(n)
else:
    pass

jb-alvarado

(Themenstarter)

Anmeldungsdatum:
28. November 2012

Beiträge: 345

Danke für deine Antwort @apt-ghetto!

Ganze so leicht ist es nicht, weil die Fehlermeldung immer kommt, auch wenn die Liste 10 Items enthält, und ich nur das letzte löschen möchte. Aber du hast mich auf die Idee gebracht einfach eine leere Zeile zum Schluss einzufügen, welche ich nicht löschbar mache - ist zwar ein unschöner Workaround, aber löst mein Problem.

Antworten |