Step 6 of getting started with wxpython (advanced components)

wxpython advanced components

In this chapter, we will discuss the following advanced components: Wx ListBox,wx.html.HtmlWindow,wx.ListCtrl.
Wxpyron has several well-known advanced components. For example, tree component, HTML window, grid part, listbox part, list part or editor with advanced style function.

wx.ListBox component

wx.ListBox is used to display and process a list of items. wx.ListBox can be created in two different states: single selection state or multi selection state. Radio status is the default status.

wx. There are two important events in the listbox. The first is Wx EVT_ COMMAND_ LISTBOX_ Selected event. When we were at Wx This event occurs when an item is selected in the listbox. The second is Wx EVT_ COMMAND_ LISTBOX_ DOUBLE_ Locked event. When we double-click Wx This event is generated when an item in the listbox. Elements are numbered from zero. If necessary, the scroll bar will be displayed automatically.

#listbox.py

import wx

class Example(wx.Frame):

    def __init__(self, *args, **kw):
        super(Example, self).__init__(*args, **kw)

        self.InitUI()

    def InitUI(self):

        panel = wx.Panel(self)
        hbox = wx.BoxSizer(wx.HORIZONTAL)

        self.listbox = wx.ListBox(panel)
        hbox.Add(self.listbox, wx.ID_ANY, wx.EXPAND | wx.ALL, 20)

        btnPanel = wx.Panel(panel)
        vbox = wx.BoxSizer(wx.VERTICAL)
        newBtn = wx.Button(btnPanel, wx.ID_ANY, 'New', size=(90, 30))
        renBtn = wx.Button(btnPanel, wx.ID_ANY, 'Rename', size=(90, 30))
        delBtn = wx.Button(btnPanel, wx.ID_ANY, 'Delete', size=(90, 30))
        clrBtn = wx.Button(btnPanel, wx.ID_ANY, 'Clear', size=(90, 30))

        self.Bind(wx.EVT_BUTTON, self.NewItem, id=newBtn.GetId())
        self.Bind(wx.EVT_BUTTON, self.OnRename, id=renBtn.GetId())
        self.Bind(wx.EVT_BUTTON, self.OnDelete, id=delBtn.GetId())
        self.Bind(wx.EVT_BUTTON, self.OnClear, id=clrBtn.GetId())
        self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRename)

        vbox.Add((-1, 20))
        vbox.Add(newBtn)
        vbox.Add(renBtn, 0, wx.TOP, 5)
        vbox.Add(delBtn, 0, wx.TOP, 5)
        vbox.Add(clrBtn, 0, wx.TOP, 5)

        btnPanel.SetSizer(vbox)
        hbox.Add(btnPanel, 0.6, wx.EXPAND | wx.RIGHT, 20)
        panel.SetSizer(hbox)

        self.SetTitle('wx.ListBox')
        self.Centre()

    def NewItem(self, event):

        text = wx.GetTextFromUser('Enter a new item', 'Insert dialog')
        if text != '':
            self.listbox.Append(text)

    def OnRename(self, event):

        sel = self.listbox.GetSelection()
        text = self.listbox.GetString(sel)
        renamed = wx.GetTextFromUser('Rename item', 'Rename dialog', text)

        if renamed != '':
            self.listbox.Delete(sel)
            item_id = self.listbox.Insert(renamed, sel)
            self.listbox.SetSelection(item_id)

    def OnDelete(self, event):

        sel = self.listbox.GetSelection()
        if sel != -1:
            self.listbox.Delete(sel)

    def OnClear(self, event):
        self.listbox.Clear()


def main():

    app = wx.App()
    ex = Example(None)
    ex.Show()
    app.MainLoop()


if __name__ == '__main__':
    main()

<img src="https://mymarkdowm.oss-cn-beijing.aliyuncs.com/markdownimg/image-20201030141224426.png" alt="image-20201030141224426" style="zoom:50%;" />

This example shows how to start from Wx Add, modify, and delete items from the listbox.

self.listbox = wx.ListBox(panel)
hbox.Add(self.listbox, wx.ID_ANY, wx.EXPAND | wx.ALL, 20)

We create an empty Wx ListBox. We add a 20px border around the list box.

self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRename)

We use Wx EVT_ COMMAND_ LISTBOX_ DOUBLE_ The clicked event binder binds a wx EVT_ LISTBOX_ Dclick event type. In this way, if we double-click a specific element in the list box, we will display a rename dialog box.

def NewItem(self, event):

    text = wx.GetTextFromUser('Enter a new item', 'Insert dialog')
    if text != '':
        self.listbox.Append(text)        

We call the NewItem() method by clicking the New button. This method uses wrapper Wx The gettextfromuser() method displays a Wx TextEntryDialog. The text we enter is returned to the text variable. If the text is not empty, we append it to the list box with the Append() method.

if renamed != '':
    self.listbox.Delete(sel)
    item_id = self.listbox.Insert(renamed, sel)
    self.listbox.SetSelection(item_id)      

We rename an item by deleting it and inserting a new item in the same location. We also set the selection back to the modified item.

def OnDelete(self, event):

    sel = self.listbox.GetSelection()
    if sel != -1:
        self.listbox.Delete(sel)

To delete an item, we find the index of the selected item by calling the GetSelection() method. Then we use the delete () method to delete the item. The parameter of the Delete() method is the selected index.

def OnClear(self, event):
    self.listbox.Clear()

The simplest is to clear the entire list box. We just need to call the Clear() method.

wx.html.HtmlWindow component

wx. html. The HTML window component displays HTML pages. It is not a mature browser. We can use Wx html. Htmlwindow components do some interesting things.

For example, in the following program, we create a window that displays basic statistics.

<!--page.html-->
<!DOCTYPE html>
<html>
<body bgcolor="#8e8e95">
  <table cellspacing="5" border="0" width="250">
    <tr width="200" align="left">
    <td bgcolor="#e7e7e7">&nbsp;&nbsp;Maximum</td>
    <td bgcolor="#aaaaaa">&nbsp;&nbsp;<b>9000</b></td>
    </tr>
    <tr align="left">
    <td bgcolor="#e7e7e7">&nbsp;&nbsp;Mean</td>
    <td bgcolor="#aaaaaa">&nbsp;&nbsp;<b>6076</b></td>
    </tr>
    <tr align="left">
    <td bgcolor="#e7e7e7">&nbsp;&nbsp;Minimum</td>
    <td bgcolor="#aaaaaa">&nbsp;&nbsp;<b>3800</b></td>
    </tr>
    <tr align="left">
    <td bgcolor="#e7e7e7">&nbsp;&nbsp;Median</td>
    <td bgcolor="#aaaaaa">&nbsp;&nbsp;<b>6000</b></td>
    </tr>
    <tr align="left">
    <td bgcolor="#e7e7e7">&nbsp;&nbsp;Standard Deviation</td>
    <td bgcolor="#aaaaaa">&nbsp;&nbsp;<b>6076</b></td>
    </tr>
  </table>
</body>
</html>

This is the HTML page to display.

#htmlwin.py

import wx
import wx.html

class Example(wx.Frame):

    def __init__(self, *args, **kw):
        super(Example, self).__init__(*args, **kw)

        self.InitUI()

    def InitUI(self):

        panel = wx.Panel(self)

        vbox = wx.BoxSizer(wx.VERTICAL)
        hbox = wx.BoxSizer(wx.HORIZONTAL)

        htmlwin = wx.html.HtmlWindow(panel, wx.ID_ANY, style=wx.NO_BORDER)
        htmlwin.SetStandardFonts()
        htmlwin.LoadPage("page.html")

        vbox.Add((-1, 10), 0)
        vbox.Add(htmlwin, 1, wx.EXPAND | wx.ALL, 9)

        bitmap = wx.StaticBitmap(panel, wx.ID_ANY, wx.Bitmap('icon_1.png'))
        hbox.Add(bitmap, 0, wx.LEFT | wx.BOTTOM | wx.TOP, 10)
        btnOk = wx.Button(panel, wx.ID_ANY, 'Ok')

        self.Bind(wx.EVT_BUTTON, self.OnClose, id=btnOk.GetId())

        hbox.Add((100, -1), 1, wx.EXPAND)
        hbox.Add(btnOk, flag=wx.TOP | wx.BOTTOM | wx.RIGHT, border=10)
        vbox.Add(hbox, 0, wx.EXPAND)

        panel.SetSizer(vbox)

        self.SetTitle('Basic statistics')
        self.Centre()

    def OnClose(self, event):
        self.Close()


def main():

    app = wx.App()
    ex = Example(None)
    ex.Show()
    app.MainLoop()


if __name__ == '__main__':
    main()

<img src="https://mymarkdowm.oss-cn-beijing.aliyuncs.com/markdownimg/image-20201030141835060.png" alt="image-20201030141835060" style="zoom:50%;" />

This example is in Wx html. Distribute an HTML file in the htmlwindow widget.

htmlwin = wx.html.HtmlWindow(panel, wx.ID_ANY, style=wx.NO_BORDER)
htmlwin.SetStandardFonts()
htmlwin.LoadPage("page.html")   

wx.html.HtmlWindow is created. Use the LoadPage() method to load the HTML file.

Help window

We can use Wx html. Htmlwindow to help our application. We can create a separate window or a window that will become part of the application. The following script will use the latter to create a help window.

# helpwindow.py

import wx
import wx.html as html


class Example(wx.Frame):

    def __init__(self,*args,**kw):
        super(Example,self).__init__(*args,**kw)

        self.InitUI()

    def InitUI(self):
        toolbar=self.CreateToolBar()
        toolbar.AddTool(1,'Exit',wx.Bitmap('icon_1.png'))
        toolbar.AddTool(2,'Help',wx.Bitmap('icon_2.png'))
        toolbar.Realize()

        self.splitter=wx.SplitterWindow(self)
        self.panelLeft=wx.Panel(self.splitter,wx.ID_ANY,style=wx.BORDER_SUNKEN)

        self.panelRight=wx.Panel(self.splitter)
        vbox2=wx.BoxSizer(wx.VERTICAL)
        header=wx.Panel(self.panelRight,wx.ID_ANY)

        header.SetBackgroundColour('#6f6a59')
        header.SetForegroundColour('white')

        hbox=wx.BoxSizer(wx.HORIZONTAL)

        st=wx.StaticText(header,wx.ID_ANY,'Help')
        font=st.GetFont()
        font.SetFamily(wx.FONTFAMILY_ROMAN)
        font.SetPointSize(11)
        st.SetFont(font)

        hbox.Add(st,1,wx.TOP | wx.BOTTOM | wx.LEFT,8)

        closeBtn=wx.BitmapButton(header,wx.ID_ANY,wx.Bitmap('icon_3.png',
                                                            wx.BITMAP_TYPE_PNG),style=wx.NO_BORDER)
        closeBtn.SetBackgroundColour('#6f6a59')

        hbox.Add(closeBtn,0,wx.TOP | wx.BOTTOM,8)
        header.SetSizer(hbox)

        vbox2.Add(header,0,wx.EXPAND)

        helpWin=html.HtmlWindow(self.panelRight,style=wx.NO_BORDER)
        helpWin.LoadPage('page.html')

        vbox2.Add(helpWin,1,wx.EXPAND)

        self.panelRight.SetSizer(vbox2)
        self.panelLeft.SetFocus()

        self.splitter.SplitVertically(self.panelLeft,self.panelRight)
        self.splitter.Unsplit()

        self.Bind(wx.EVT_BUTTON,self.CloseHelp,id=closeBtn.GetId())
        self.Bind(wx.EVT_TOOL,self.OnClose,id=1)
        self.Bind(wx.EVT_TOOL,self.OnHelp,id=2)

        self.panelLeft.Bind(wx.EVT_KEY_DOWN,self.OnKeyPressed)
        self.panelLeft.SetFocus()

        self.CreateStatusBar()

        self.SetTitle('Help')
        self.Centre()

    def OnClose(self,e):
        self.Close()

    def OnHelp(self,e):
        self.splitter.SplitVertically(self.panelLeft,self.panelRight)
        self.panelLeft.SetFocus()

    def CloseHelp(self,e):
        self.splitter.Unsplit()
        self.panelLeft.SetFocus()

    def OnKeyPressed(self,e):
        keycode=e.GetKeyCode()
        print(keycode)

        if keycode == wx.WXK_F1:
            self.splitter.SplitVertically(self.panelLeft,self.panelRight)
            self.panelLeft.SetFocus()


def main():
    app=wx.App()
    ex=Example(None)
    ex.Show()
    app.MainLoop()


if __name__ == '__main__':
    main()

<img src="https://mymarkdowm.oss-cn-beijing.aliyuncs.com/markdownimg/image-20201030142310825.png" alt="image-20201030142310825" style="zoom:50%;" />

The help window is hidden at the beginning. We can display it by clicking the help button on the toolbar or pressing F1. We can display it by clicking the help button on the toolbar or pressing F1. The help window will appear on the right side of the application. To hide the help window, we click the close button.

self.splitter.SplitVertically(self.panelLeft, self.panelRight)
self.splitter.Unsplit()

We create the left and right panels and divide them vertically. After that, we call the Unsplit() method. By default, this method hides the right or bottom panel.

We divide the right panel into two parts. The body of the head and panel. The head is an adjusted Wx Panel. The header consists of a static text and a bitmap button. We put Wx html. Place window in the body of the panel.

closeBtn = wx.BitmapButton(header, wx.ID_ANY, wx.Bitmap('closebutton.png',
      wx.BITMAP_TYPE_PNG), style=wx.NO_BORDER)
closeBtn.SetBackgroundColour('#6f6a59')

Set the bitmap button style to Wx NO_ BORDER. The background color is set to the color of the title Panel to make the button look like part of the title. The purpose of this is to make the button appear as part of the header.

helpWin = html.HtmlWindow(self.panelRight, style=wx.NO_BORDER)
helpWin.LoadPage('page.html')

Let's create a Wx on the right panel html. Htmlwindow widget. Our HTML code is in a separate file. This time, we call the LoadPage() method to get the HTML code.

self.panelLeft.Bind(wx.EVT_KEY_DOWN, self.OnKeyPressed)
self.panelLeft.SetFocus()

We set the focus on the left panel. We can use the F1 key to start the help window. In order to control a window with the keyboard, it must have focus. If we don't set the focus, we must first click on the panel, so that we can start the help window by pressing F1.

def OnHelp(self, e):

    self.splitter.SplitVertically(self.panelLeft, self.panelRight)
    self.panelLeft.SetFocus()

To display the help window, we call the OnHelp() method. It divides the two panels vertically. Let's not forget to set the focus again, because the initial focus will be lost due to segmentation.

wx.ListCtrl component

wx.ListCtrl is a graphical representation of a list of items. A Wx Listbox can only have one column, while Wx ListCtrl can have more than one column. For example, a file manager uses Wx ListCtrl to display directories and files in the file system. A CD burning program in Wx ListCtrl displays the files to burn.

A Wx ListCtrl can be used in three different styles. List view, report view, or icon view. These styles are created by Wx ListCtrl window style control, Wx LC_ REPORT,wx.LC_LIST and Wx LC_ ICON.

wx.ListCtrl style

  • wx.LC_LIST
  • wx.LC_REPORT
  • wx.LC_VIRTUAL
  • wx.LC_ICON
  • wx.LC_SMALL_ICON
  • wx.LC_ALIGN_LEFT
  • wx.LC_EDIT_LABELS
  • wx.LC_NO_HEADER
  • wx.LC_SORT_ASCENDING
  • wx.LC_SORT_DESCENDING
  • wx.LC_HRULES
  • wx.LC_VRULES

wx.ListCtrl example

#listctrl_exam.py

import wx

data = [('Jessica Alba', 'Pomona', '1981'), ('Sigourney Weaver', 'New York', '1949'),
  ('Angelina Jolie', 'los angeles', '1975'), ('Natalie Portman', 'Jerusalem', '1981'),
  ('Rachel Weiss', 'London', '1971'), ('Scarlett Johansson', 'New York', '1984' )]


class Example(wx.Frame):

    def __init__(self, *args, **kw):
        super(Example, self).__init__(*args, **kw)

        self.InitUI()

    def InitUI(self):

        hbox = wx.BoxSizer(wx.HORIZONTAL)
        panel = wx.Panel(self)

        self.list = wx.ListCtrl(panel, wx.ID_ANY, style=wx.LC_REPORT)
        self.list.InsertColumn(0, 'name', width=140)
        self.list.InsertColumn(1, 'place', width=130)
        self.list.InsertColumn(2, 'year', wx.LIST_FORMAT_RIGHT, 90)

        idx = 0

        for i in data:

            index = self.list.InsertItem(idx, i[0])
            self.list.SetItem(index, 1, i[1])
            self.list.SetItem(index, 2, i[2])
            idx += 1

        hbox.Add(self.list, 1, wx.EXPAND)
        panel.SetSizer(hbox)

        self.SetTitle('Actresses')
        self.Centre()


def main():

    app = wx.App()
    ex = Example(None)
    ex.Show()
    app.MainLoop()


if __name__ == '__main__':
    main()

<img src="https://mymarkdowm.oss-cn-beijing.aliyuncs.com/markdownimg/image-20201030142803996.png" alt="image-20201030142803996" style="zoom:50%;" />

The code example is in Wx Show data about actresses in ListCtrl.

self.list = wx.ListCtrl(panel, wx.ID_ANY, style=wx.LC_REPORT)

We create one with Wx LC_ Report style Wx ListCtrl.

self.list.InsertColumn(0, 'name', width=140)
self.list.InsertColumn(1, 'place', width=130)
self.list.InsertColumn(2, 'year', wx.LIST_FORMAT_RIGHT, 90)

We insert three columns. We can specify the width of the column and the format of the column. The default format is Wx LIST_ FORMAT_ LEFT.

idx = 0

for i in data:

    index = self.list.InsertItem(idx, i[0])
    self.list.SetItem(index, 1, i[1])
    self.list.SetItem(index, 2, i[2])
    idx += 1

We use two methods to insert data into Wx ListCtrl. Each line starts with the InsertItem() method. The first parameter of the method specifies the line number. This method returns the index of the row. The SetItem() method adds data to the contiguous columns of the current row.

Mixins

Mixins is further enhanced Wx Class of ListCtrl function. They are located in Wx lib. mixins. ListCtrl module. In order to use them, we must inherit the functions of these classes.

There are six mixins.

  • wx.ColumnSorterMixin
  • wx.ListCtrlAutoWidthMixin
  • wx.ListCtrlSelectionManagerMix
  • wx.TextEditMixin
  • wx.CheckListCtrlMixin
  • wx.ListRowHighlighter

wx.ColumnSorterMixin is a mixin that can sort columns in the report view. wx. The listctrlauutowidthmixin class can automatically resize the last column to Wx End of ListCtrl. By default, the last column does not occupy the remaining space. Look at the previous example. wx.ListCtrlSelectionManagerMix defines a platform independent selection policy. wx.TextEditMixin can edit text. wx.CheckListCtrlMixin adds a check box for each row. So we can control the line. We can set each row to be checked or unchecked. wx.ListRowHighlighter handles Wx Automatic background highlighting of alternating rows in ListCtrl.

wx.lib.mixins.listctrl.ListCtrlAutoWidthMixin

The following code shows how we use Wx lib. mixins. listctrl. ListCtrlAutoWidthMixin

#autowidth.py

import wx
import wx.lib.mixins.listctrl

data = [('Jessica Alba', 'Pomona', '1981'), ('Sigourney Weaver', 'New York', '1949'),
  ('Angelina Jolie', 'Los Angeles', '1975'), ('Natalie Portman', 'Jerusalem', '1981'),
  ('Rachel Weiss', 'London', '1971'), ('Scarlett Johansson', 'New York', '1984')]


class AutoWidthListCtrl(wx.ListCtrl, wx.lib.mixins.listctrl.ListCtrlAutoWidthMixin):

    def __init__(self, parent, *args, **kw):
        wx.ListCtrl.__init__(self, parent, wx.ID_ANY, style=wx.LC_REPORT)
        wx.lib.mixins.listctrl.ListCtrlAutoWidthMixin.__init__(self)


class Example(wx.Frame):

    def __init__(self, *args, **kw):
        super(Example, self).__init__(*args, **kw)
        
        self.InitUI()

    def InitUI(self):        

        hbox = wx.BoxSizer(wx.HORIZONTAL)

        panel = wx.Panel(self)

        self.list = AutoWidthListCtrl(panel)
        self.list.InsertColumn(0, 'name', width=140)
        self.list.InsertColumn(1, 'place', width=130)
        self.list.InsertColumn(2, 'year', wx.LIST_FORMAT_RIGHT, 90)

        idx = 0

        for i in data:

            index = self.list.InsertItem(idx, i[0])
            self.list.SetItem(index, 1, i[1])
            self.list.SetItem(index, 2, i[2])
            idx += 1

        hbox.Add(self.list, 1, wx.EXPAND)
        panel.SetSizer(hbox)

        self.SetTitle('Actresses')
        self.Centre()


def main():

    app = wx.App()
    ex = Example(None)
    ex.Show()
    app.MainLoop()


if __name__ == '__main__':
    main()

<img src="https://mymarkdowm.oss-cn-beijing.aliyuncs.com/markdownimg/image-20201030143105149.png" alt="image-20201030143105149" style="zoom:50%;" />

Let's change the previous example.

import wx.lib.mixins.listctrl

Here we import the mixin module.

class AutoWidthListCtrl(wx.ListCtrl, wx.lib.mixins.listctrl.ListCtrlAutoWidthMixin):

    def __init__(self, parent, *args, **kw):
        wx.ListCtrl.__init__(self, parent, wx.ID_ANY, style=wx.LC_REPORT)
        wx.lib.mixins.listctrl.ListCtrlAutoWidthMixin.__init__(self)

We create a new AutoWidthListCtrl class. This class inherits from Wx ListCtrl and Wx lib. mixins. listctrl. ListCtrlAutoWidthMixin. This is called multi inheritance. The last column is automatically resized to take up Wx The remaining width of ListCtrl.

wx.lib.mixins.listctrl.ColumnSorterMixin

The following example creates a sortable column. If we click on the column header, the corresponding rows in the column will be sorted.

#sorted.py

import wx
import wx.lib.mixins.listctrl

actresses = {
1 : ('Jessica Alba', 'Pomona', '1981'),
2 : ('Sigourney Weaver', 'New York', '1949'),
3 : ('Angelina Jolie', 'Los Angeles', '1975'),
4 : ('Natalie Portman', 'Jerusalem', '1981'),
5 : ('Rachel Weiss', 'London', '1971'),
6 : ('Scarlett Johansson', 'New York', '1984')
}


class SortedListCtrl(wx.ListCtrl, wx.lib.mixins.listctrl.ColumnSorterMixin):

    def __init__(self, parent):

        wx.ListCtrl.__init__(self, parent, wx.ID_ANY, style=wx.LC_REPORT)
        wx.lib.mixins.listctrl.ColumnSorterMixin.__init__(self, len(actresses))
        self.itemDataMap = actresses

    def GetListCtrl(self):
        return self
        

class Example(wx.Frame):

    def __init__(self, *args, **kw):
        super(Example, self).__init__(*args, **kw)
        
        self.InitUI()

    def InitUI(self):        

        hbox = wx.BoxSizer(wx.HORIZONTAL)
        panel = wx.Panel(self)

        self.list = SortedListCtrl(panel)
        self.list.InsertColumn(0, 'name', width=140)
        self.list.InsertColumn(1, 'place', width=130)
        self.list.InsertColumn(2, 'year', wx.LIST_FORMAT_RIGHT, 90)

        items = actresses.items()

        idx = 0

        for key, data in items:

            index = self.list.InsertItem(idx, data[0])
            self.list.SetItem(index, 1, data[1])
            self.list.SetItem(index, 2, data[2])
            self.list.SetItemData(index, key)
            idx += 1

        hbox.Add(self.list, 1, wx.EXPAND)
        panel.SetSizer(hbox)

        self.SetTitle('Actresses')
        self.Centre()


def main():

    app = wx.App()
    ex = Example(None)
    ex.Show()
    app.MainLoop()


if __name__ == '__main__':
    main()

<img src="https://mymarkdowm.oss-cn-beijing.aliyuncs.com/markdownimg/image-20201030143320812.png" alt="image-20201030143320812" style="zoom:50%;" />

Let's take an actress as an example.

wx.lib.mixins.listctrl.ColumnSorterMixin.__init__(self, len(actresses))

wx.lib.mixins.listctrl.ColumnSorterMixin accepts a parameter: the number of columns to sort.

self.itemDataMap = actresses

We must map the data we want to display in the list control to the itemDataMap property. Data must be a dictionary data type.

def GetListCtrl(self):
    return self

We must create a GetListCtrl() method. This method returns the Wx to be sorted ListCtrl widget.

self.list.SetItemData(index, key)

We must assign a special index to each row. This is done through the SetItemData method.

wx.lib.mixins.listctrl.CheckListCtrl

You can place a check box in a list control. In Wx python, we can use Wx lib. mixins. listctrl. CheckListCtrl.

#repository.py

import wx
from wx.lib.mixins.listctrl import CheckListCtrlMixin, ListCtrlAutoWidthMixin

packages = [('abiword', '5.8M', 'base'), ('adie', '145k', 'base'),
    ('airsnort', '71k', 'base'), ('ara', '717k', 'base'), ('arc', '139k', 'base'),
    ('asc', '5.8M', 'base'), ('ascii', '74k', 'base'), ('ash', '74k', 'base')]

class CheckListCtrl(wx.ListCtrl, CheckListCtrlMixin, ListCtrlAutoWidthMixin):

    def __init__(self, parent):
        wx.ListCtrl.__init__(self, parent, wx.ID_ANY, style=wx.LC_REPORT |
                wx.SUNKEN_BORDER)
        CheckListCtrlMixin.__init__(self)
        ListCtrlAutoWidthMixin.__init__(self)


class Example(wx.Frame):

    def __init__(self, *args, **kw):
        super(Example, self).__init__(*args, **kw)

        panel = wx.Panel(self)

        vbox = wx.BoxSizer(wx.VERTICAL)
        hbox = wx.BoxSizer(wx.HORIZONTAL)

        leftPanel = wx.Panel(panel)
        rightPanel = wx.Panel(panel)

        self.log = wx.TextCtrl(rightPanel, style=wx.TE_MULTILINE|wx.TE_READONLY)
        self.list = CheckListCtrl(rightPanel)
        self.list.InsertColumn(0, 'Package', width=140)
        self.list.InsertColumn(1, 'Size')
        self.list.InsertColumn(2, 'Repository')

        idx = 0

        for i in packages:

            index = self.list.InsertItem(idx, i[0])
            self.list.SetItem(index, 1, i[1])
            self.list.SetItem(index, 2, i[2])
            idx += 1

        vbox2 = wx.BoxSizer(wx.VERTICAL)

        selBtn = wx.Button(leftPanel, label='Select All')
        desBtn = wx.Button(leftPanel, label='Deselect All')
        appBtn = wx.Button(leftPanel, label='Apply')

        self.Bind(wx.EVT_BUTTON, self.OnSelectAll, id=selBtn.GetId())
        self.Bind(wx.EVT_BUTTON, self.OnDeselectAll, id=desBtn.GetId())
        self.Bind(wx.EVT_BUTTON, self.OnApply, id=appBtn.GetId())

        vbox2.Add(selBtn, 0, wx.TOP|wx.BOTTOM, 5)
        vbox2.Add(desBtn, 0, wx.BOTTOM, 5)
        vbox2.Add(appBtn)

        leftPanel.SetSizer(vbox2)

        vbox.Add(self.list, 4, wx.EXPAND | wx.TOP, 3)
        vbox.Add((-1, 10))
        vbox.Add(self.log, 1, wx.EXPAND)
        vbox.Add((-1, 10))

        rightPanel.SetSizer(vbox)

        hbox.Add(leftPanel, 0, wx.EXPAND | wx.RIGHT, 5)
        hbox.Add(rightPanel, 1, wx.EXPAND)
        hbox.Add((3, -1))

        panel.SetSizer(hbox)

        self.SetTitle('Repository')
        self.Centre()

    def OnSelectAll(self, event):

        num = self.list.GetItemCount()
        for i in range(num):
            self.list.CheckItem(i)

    def OnDeselectAll(self, event):

        num = self.list.GetItemCount()
        for i in range(num):
            self.list.CheckItem(i, False)

    def OnApply(self, event):

        num = self.list.GetItemCount()

        for i in range(num):

            if i == 0: self.log.Clear()

            if self.list.IsChecked(i):
                self.log.AppendText(self.list.GetItemText(i) + '\n')


def main():

    app = wx.App()
    ex = Example(None)
    ex.Show()
    app.MainLoop()


if __name__ == '__main__':
    main()

<img src="https://mymarkdowm.oss-cn-beijing.aliyuncs.com/markdownimg/image-20201030143806315.png" alt="image-20201030143806315" style="zoom:50%;" />

This example uses Wx lib. mixins. listctrl. Checklistctrl creates a version library UI.

class CheckListCtrl(wx.ListCtrl, CheckListCtrlMixin, ListCtrlAutoWidthMixin):

    def __init__(self, parent):
        wx.ListCtrl.__init__(self, parent, wx.ID_ANY, style=wx.LC_REPORT |
                wx.SUNKEN_BORDER)
        CheckListCtrlMixin.__init__(self)
        ListCtrlAutoWidthMixin.__init__(self)

We inherit from three different classes.

def OnSelectAll(self, event):
   
    num = self.list.GetItemCount()
    
    for i in range(num):
        self.list.CheckItem(i)

The OnSelectAll() method selects all check boxes. GetItemCount() determines the number of items, and the CheckItem() method marks the current check box.

Tags: Python

Posted by kankaro on Mon, 09 May 2022 20:44:37 +0300