WxPython FAQ Advanced Widgets

Материал из Wiki.crossplatform.ru

(Различия между версиями)
Перейти к: навигация, поиск
(Удалено по требованию автора...)
 
Строка 1: Строка 1:
-
In the following chapters we will talk about advanced widgets. A big advantage of wxPython over a competing PyGTK is the availability of a huge amount of advanced widgets. PyGTK is a layer over a C based GKT+ toolkit. It does not provide new widgets. In contrast, wxPython is a layer over wxWidgets a C++ based toolkit. wxWidgets consists of a large group of widgets. All this widgets are created in C++. wxPython is a glue that combines python language with this toolkit. If we want to have a grid widget in our application using PyGTK, we have to create it ourselves. Such a widget is quite complicated. Not to mention the speed penalty. Dynamic languages like Python, PERL or Ruby are not suitable for such tasks.
 
-
Dynamic languages are great in various areas. They are simple to use. They are great for prototyping, in house developing or for studying computer programming. If we need a quick solution or we need an application, that will change rapidly over a short period of time, dynamic languages are superior to compiled languages.
 
-
On the other hand, if we develop resource intensive applications, games, high quality multimedia applications, there is no competition to C++.
 
-
wxPython has several well known advanced widgets. For example a tree widget, an html window, a grid widget, a listbox widget, a list widget or an editor with advanced styling capabilities.
 
-
wxPython and wxWidgets are being developed all the time. New widgets and features emerge with every major release. At the time when I write these words a wxPython 2.8.3.0 has been released just two days ago.
 
-
(22-Mar-2007).
 
-
 
-
== A wx.ListBox widget ==
 
-
A <i>wx.ListBox</i> widget is used for displaying and working with a list of items. As it's name indicates, it is a rectangle that has a list of strings inside. We could use it for displaying a list of mp3 files, book names, module names of a larger project or names of our friends.  A <i>wx.ListBox</i> can be created in two different states. In a single selection state or a multiple selection state. The single selection state is the default state. There are two significant events in <i>wx.ListBox</i>. The first one is the <i>wx.EVT_COMMAND_LISTBOX_SELECTED</i> event. This event is generated when we select a string in a <i>wx.ListBox</i>. The second one is the <i>wx.EVT_COMMAND_LISTBOX_DOUBLE_CLICKED</i> event. It is generated when we double click an item in a <i>wx.ListBox</i>. The number of elements inside a wx.ListBox is limited on GTK platform. According to the documentation, it is currently around 2000 elements. Quite enough, I think. The elements are numbered from zero. Scrollbars are displayed automatically if needed.
 
-
 
-
The constructor of a wx.ListBox widget is as follows:
 
-
<source lang="python">
 
-
wx.ListBox(wx.Window parent, int id=-1, wx.Point pos=wx.DefaultPosition, wx.Size size=wx.DefaultSize,
 
-
list choices=[], long style=0, wx.Validator validator=wx.DefaultValidator,
 
-
string name=wx.ListBoxNameStr)
 
-
</source>
 
-
There is a choices parameter. If we put some values there, they will be displayed from the construction of the widget.
 
-
This parameter is empty by default.
 
-
 
-
In our code example we have a listbox and four buttons. Each of them calls a different method of our listbox.
 
-
If we want to append a new item, we call the <i>Append()</i> method. If we want to delete an item, we call the <i>Delete()</i> method. To clear all strings in a listbox, we call the Clear() method.
 
-
 
-
<source lang="python">
 
-
#!/usr/bin/python
 
-
# listbox.py
 
-
 
-
import wx
 
-
 
-
ID_NEW = 1
 
-
ID_RENAME = 2
 
-
ID_CLEAR = 3
 
-
ID_DELETE = 4
 
-
 
-
class ListBox(wx.Frame):
 
-
    def __init__(self, parent, id, title):
 
-
        wx.Frame.__init__(self, parent, id, title, size=(350, 220))
 
-
 
-
        panel = wx.Panel(self, -1)
 
-
        hbox = wx.BoxSizer(wx.HORIZONTAL)
 
-
 
-
        self.listbox = wx.ListBox(panel, -1)
 
-
        hbox.Add(self.listbox, 1, wx.EXPAND | wx.ALL, 20)
 
-
 
-
        btnPanel = wx.Panel(panel, -1)
 
-
        vbox = wx.BoxSizer(wx.VERTICAL)
 
-
        new = wx.Button(btnPanel, ID_NEW, 'New', size=(90, 30))
 
-
        ren = wx.Button(btnPanel, ID_RENAME, 'Rename', size=(90, 30))
 
-
        dlt = wx.Button(btnPanel, ID_DELETE, 'Delete', size=(90, 30))
 
-
        clr = wx.Button(btnPanel, ID_CLEAR, 'Clear', size=(90, 30))
 
-
 
-
        self.Bind(wx.EVT_BUTTON, self.NewItem, id=ID_NEW)
 
-
        self.Bind(wx.EVT_BUTTON, self.OnRename, id=ID_RENAME)
 
-
        self.Bind(wx.EVT_BUTTON, self.OnDelete, id=ID_DELETE)
 
-
        self.Bind(wx.EVT_BUTTON, self.OnClear, id=ID_CLEAR)
 
-
        self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRename)
 
-
 
-
        vbox.Add((-1, 20))
 
-
        vbox.Add(new)
 
-
        vbox.Add(ren, 0, wx.TOP, 5)
 
-
        vbox.Add(dlt, 0, wx.TOP, 5)
 
-
        vbox.Add(clr, 0, wx.TOP, 5)
 
-
 
-
        btnPanel.SetSizer(vbox)
 
-
        hbox.Add(btnPanel, 0.6, wx.EXPAND | wx.RIGHT, 20)
 
-
        panel.SetSizer(hbox)
 
-
 
-
        self.Centre()
 
-
        self.Show(True)
 
-
 
-
    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)
 
-
            self.listbox.Insert(renamed, sel)
 
-
 
-
 
-
    def OnDelete(self, event):
 
-
        sel = self.listbox.GetSelection()
 
-
        if sel != -1:
 
-
            self.listbox.Delete(sel)
 
-
 
-
    def OnClear(self, event):
 
-
        self.listbox.Clear()
 
-
 
-
 
-
app = wx.App()
 
-
ListBox(None, -1, 'ListBox')
 
-
app.MainLoop()
 
-
</source>
 
-
 
-
<source lang="python">
 
-
self.listbox = wx.ListBox(panel, -1)
 
-
hbox.Add(self.listbox, 1, wx.EXPAND | wx.ALL, 20)
 
-
</source>
 
-
We create an empty <i>wx.ListBox</i>. We put a 20px border around the listbox.
 
-
 
-
<source lang="python">
 
-
self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRename)
 
-
</source>
 
-
 
-
We bind a <i>wx.EVT_COMMAND_LISTBOX_DOUBLE_CLICKED</i> event type with the <i>OnRename()</i> method using the <i>wx.EVT_LISTBOX_DCLICK</i> event binder. This way we show a rename dialog if we double click on a specific element in the listbox.
 
-
 
-
<source lang="python">
 
-
def NewItem(self, event):
 
-
    text = wx.GetTextFromUser('Enter a new item', 'Insert dialog')
 
-
    if text != '':
 
-
        self.listbox.Append(text)
 
-
</source>
 
-
 
-
We call the <i>NewItem()</i> method by clicking on the New button. This method shows a <i>wx.GetTextFromUser</i> dialog window.
 
-
The text that we enter is returned to the text variable. If the text is not empty, we append it to the listbox with the <i>Append()</i> method.
 
-
 
-
<source lang="python">
 
-
def OnDelete(self, event):
 
-
    sel = self.listbox.GetSelection()
 
-
    if sel != -1:
 
-
        self.listbox.Delete(sel)
 
-
</source>
 
-
 
-
Deleting an item is done in two steps. First we find the index of the selected item by calling the <i>GetSelection()</i> method.
 
-
Then we delete the item with the <i>Delete()</i> method. The parametor to the <i>Delete()</i> method is the selected index.
 
-
 
-
<source lang="python">
 
-
 
-
self.listbox.Delete(sel)
 
-
self.listbox.Insert(renamed, sel)
 
-
</source>
 
-
 
-
Notice, how we managed to rename a string. <i>wx.ListBox</i> widget has no Rename() method. We did this functionality by deleting the previously selected string and inserting a new string into the predecessor's position.
 
-
 
-
<source lang="python">
 
-
def OnClear(self, event):
 
-
    self.listbox.Clear()
 
-
</source>
 
-
 
-
The easiest thing is to clear the whole listbox. We simply call the <i>Clear()</i> method.
 
-
 
-
[[image: wxPython_faq_listbox2.png | center]]
 
-
 
-
== A wx.html.HtmlWindow widget ==
 
-
The <i>wx.html.HtmlWindow</i> widget displays html pages. It is not a full-fledged browser. We can do interesting things with <i>wx.html.HtmlWindow</i> widget.
 
-
 
-
=== Special formatting ===
 
-
 
-
For example in the following script we will create a window, that will display basic statistics.
 
-
This formatting would be very hard if possible to create without <i>wx.html.HtmlWindow</i> widget.
 
-
 
-
<source lang="python">
 
-
#!/usr/bin/python
 
-
 
-
import wx
 
-
import wx.html as html
 
-
 
-
ID_CLOSE = 1
 
-
 
-
page = '&lt;html&gt;&lt;body bgcolor="#8e8e95"&gt;&lt;table cellspacing="5" border="0" width="250"> \
 
-
 
-
&lt;tr width="200" align="left"&gt; \
 
-
&lt;td bgcolor="#e7e7e7">&amp;nbsp;&amp;nbsp;Maximum&lt;/td&gt; \
 
-
&lt;td bgcolor="#aaaaaa"&gt;&amp;nbsp;&amp;nbsp;&lt;b&gt;9000&lt;/b&gt;&lt;/td&gt; \
 
-
 
-
&lt;/tr&gt; \
 
-
&lt;tr align="left"&gt; \
 
-
&lt;td bgcolor="#e7e7e7"&gt;&amp;nbsp;&amp;nbsp;Mean&lt;/td&gt; \
 
-
&lt;td bgcolor="#aaaaaa">&amp;nbsp;&amp;nbsp;&lt;b&gt;6076&lt;/b&gt;&lt;/td&gt; \
 
-
 
-
&lt;/tr&gt; \
 
-
&lt;tr align="left"> \
 
-
&lt;td bgcolor="#e7e7e7">&amp;nbsp;&amp;nbsp;Minimum&lt;/td&gt; \
 
-
&lt;td bgcolor="#aaaaaa"&gt;&amp;nbsp;&amp;nbsp;&lt;b&gt;3800&lt;/b&gt;&lt;/td&gt; \
 
-
 
-
&lt;/tr&gt; \
 
-
&lt;tr align="left"&gt; \
 
-
&lt;td bgcolor="#e7e7e7"&gt;&amp;nbsp;&amp;nbsp;Median&lt;/td&gt; \
 
-
&lt;td bgcolor="#aaaaaa"&gt;&amp;nbsp;&amp;nbsp;&lt;b&gt;6000&lt;/b&gt;&lt;/td&gt; \
 
-
 
-
&lt;/tr&gt; \
 
-
&lt;tr align="left"&gt; \
 
-
&lt;td bgcolor="#e7e7e7"&gt;&amp;nbsp;&amp;nbsp;Standard Deviation&lt;/td&gt; \
 
-
&lt;td bgcolor="#aaaaaa"&gt;&amp;nbsp;&amp;nbsp;&lt;b&gt;6076&lt;/b&gt;&lt;/td&gt; \
 
-
 
-
&lt;/tr&gt; \
 
-
&lt;/body&gt;&lt;/table&gt;&lt;/html&gt;'
 
-
 
-
 
-
class MyFrame(wx.Frame):
 
-
    def __init__(self, parent, id, title):
 
-
        wx.Frame.__init__(self, parent, id, title, size=(400, 290))
 
-
 
-
        panel = wx.Panel(self, -1)
 
-
 
-
        vbox = wx.BoxSizer(wx.VERTICAL)
 
-
        hbox = wx.BoxSizer(wx.HORIZONTAL)
 
-
 
-
        htmlwin = html.HtmlWindow(panel, -1, style=wx.NO_BORDER)
 
-
        htmlwin.SetBackgroundColour(wx.RED)
 
-
        htmlwin.SetStandardFonts()
 
-
        htmlwin.SetPage(page)
 
-
 
-
        vbox.Add((-1, 10), 0)
 
-
        vbox.Add(htmlwin, 1, wx.EXPAND | wx.ALL, 9)
 
-
 
-
        bitmap = wx.StaticBitmap(panel, -1, wx.Bitmap('images/newt.png'))
 
-
        hbox.Add(bitmap, 1, wx.LEFT | wx.BOTTOM | wx.TOP, 10)
 
-
        buttonOk = wx.Button(panel, ID_CLOSE, 'Ok')
 
-
 
-
        self.Bind(wx.EVT_BUTTON, self.OnClose, id=ID_CLOSE)
 
-
 
-
        hbox.Add((100, -1), 1, wx.EXPAND | wx.ALIGN_RIGHT)
 
-
        hbox.Add(buttonOk, flag=wx.TOP | wx.BOTTOM | wx.RIGHT, border=10)
 
-
        vbox.Add(hbox, 0, wx.EXPAND)
 
-
 
-
        panel.SetSizer(vbox)
 
-
        self.Centre()
 
-
        self.Show(True)
 
-
 
-
    def OnClose(self, event):
 
-
        self.Close()
 
-
 
-
app = wx.App(0)
 
-
MyFrame(None, -1, 'Basic Statistics')
 
-
app.MainLoop()
 
-
</source>
 
-
 
-
[[image: wxPython_faq_basicw.jpg | center]]
 
-
 
-
=== Help window ===
 
-
 
-
We can use <i>wx.html.HtmlWindow</i> to provide help in our application. We can create a standalone window or we can create a window, that is going to be a part of the application.  The following script will create a help window using the latter idea.
 
-
 
-
<source lang="python">
 
-
#!/usr/bin/python
 
-
# helpwindow.py
 
-
 
-
import wx
 
-
import wx.html as html
 
-
 
-
class HelpWindow(wx.Frame):
 
-
    def __init__(self, parent, id, title):
 
-
        wx.Frame.__init__(self, parent, id, title, size=(570, 400))
 
-
 
-
        toolbar = self.CreateToolBar()
 
-
        toolbar.AddLabelTool(1, 'Exit', wx.Bitmap('icons/exit.png'))
 
-
        toolbar.AddLabelTool(2, 'Help', wx.Bitmap('icons/help.png'))
 
-
        toolbar.Realize()
 
-
 
-
        self.splitter = wx.SplitterWindow(self, -1)
 
-
        self.panelLeft = wx.Panel(self.splitter, -1, style=wx.BORDER_SUNKEN)
 
-
 
-
        self.panelRight = wx.Panel(self.splitter, -1)
 
-
        vbox2 = wx.BoxSizer(wx.VERTICAL)
 
-
        header = wx.Panel(self.panelRight, -1, size=(-1, 20))
 
-
        header.SetBackgroundColour('#6f6a59')
 
-
        header.SetForegroundColour('WHITE')
 
-
        hbox = wx.BoxSizer(wx.HORIZONTAL)
 
-
 
-
        st = wx.StaticText(header, -1, 'Help', (5, 5))
 
-
        font = st.GetFont()
 
-
        font.SetPointSize(9)
 
-
        st.SetFont(font)
 
-
        hbox.Add(st, 1, wx.TOP | wx.BOTTOM | wx.LEFT, 5)
 
-
 
-
        close = wx.BitmapButton(header, -1, wx.Bitmap('icons/fileclose.png', wx.BITMAP_TYPE_PNG),
 
-
style=wx.NO_BORDER)
 
-
        close.SetBackgroundColour('#6f6a59')
 
-
        hbox.Add(close, 0)
 
-
        header.SetSizer(hbox)
 
-
 
-
        vbox2.Add(header, 0, wx.EXPAND)
 
-
 
-
        help = html.HtmlWindow(self.panelRight, -1, style=wx.NO_BORDER)
 
-
        help.LoadPage('help.html')
 
-
        vbox2.Add(help, 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=close.GetId())
 
-
        self.Bind(wx.EVT_TOOL, self.OnClose, id=1)
 
-
        self.Bind(wx.EVT_TOOL, self.OnHelp, id=2)
 
-
 
-
        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyPressed)
 
-
 
-
        self.CreateStatusBar()
 
-
 
-
        self.Centre()
 
-
        self.Show(True)
 
-
 
-
    def OnClose(self, event):
 
-
        self.Close()
 
-
 
-
    def OnHelp(self, event):
 
-
        self.splitter.SplitVertically(self.panelLeft, self.panelRight)
 
-
        self.panelLeft.SetFocus()
 
-
 
-
    def CloseHelp(self, event):
 
-
        self.splitter.Unsplit()
 
-
        self.panelLeft.SetFocus()
 
-
 
-
    def OnKeyPressed(self, event):
 
-
        keycode = event.GetKeyCode()
 
-
        if keycode == wx.WXK_F1:
 
-
            self.splitter.SplitVertically(self.panelLeft, self.panelRight)
 
-
            self.panelLeft.SetFocus()
 
-
 
-
 
-
app = wx.App()
 
-
HelpWindow(None, -1, 'HelpWindow')
 
-
app.MainLoop()
 
-
</source>
 
-
 
-
The help window is hidden in the beginning. We can show it by clicking on the help button on the toolbar or by pressing F1.
 
-
The help window appears on the right side of the application. To hide the help window, we click on the close button.
 
-
 
-
<source lang="python">
 
-
 
-
self.splitter.SplitVertically(self.panelLeft, self.panelRight)
 
-
self.splitter.Unsplit()
 
-
</source>
 
-
 
-
We create left a right panels and split them vertically. After that, we call the <i>Unsplit()</i> method. By default the method hides the right or bottom panes.
 
-
 
-
We divide the right panel into two parts. The header and the body of the panel. The header is an adjusted <i>wx.Panel</i>. The header consists of a static text and a bitmap button. We put <i>wx.html.Window</i> into the body of the panel.
 
-
 
-
<source lang="python">
 
-
close = wx.BitmapButton(header, -1, wx.Bitmap('icons/fileclose.png', wx.BITMAP_TYPE_PNG),
 
-
style=wx.NO_BORDER)
 
-
close.SetBackgroundColour('#6f6a59')
 
-
</source>
 
-
 
-
The bitmap button style is set to <i>wx.NO_BORDER</i>. The background color is set to the color of the header panel. This is done in order to make the button appear as a part of the header.
 
-
 
-
<source lang="python">
 
-
help = html.HtmlWindow(self.panelRight, -1, style=wx.NO_BORDER)
 
-
help.LoadPage('help.html')
 
-
 
-
</source>
 
-
 
-
We create a <a>wx.html.HtmlWindow</a> widget on the right panel. We have our html code in a separate file. This time we call the <i>LoadPage()</i> method to obtain the html code. 
 
-
 
-
<source lang="python">
 
-
self.panelLeft.SetFocus()
 
-
</source>
 
-
 
-
We set focus on the left panel. We can launch the help window with the F1 key. In order to control a window with a keyboard, it must have the focus. If we did not set the focus, we would have to first click on the panel and only then we could launch the help window with the F1 key press.
 
-
 
-
<source lang="python">
 
-
    def OnHelp(self, event):
 
-
        self.splitter.SplitVertically(self.panelLeft, self.panelRight)
 
-
        self.panelLeft.SetFocus()
 
-
</source>
 
-
 
-
To show the help window, we call the <i>OnHelp()</i> method. It splits the two panels vertically. We must not forget to  set the focus again, because the initial focus is lost by splitting.
 
-
 
-
The following is the html file, that we load in our application.
 
-
 
-
<source lang="python">
 
-
&lt;html&gt;
 
-
 
-
&lt;body bgcolor="#ababab"&gt;
 
-
&lt;h4&gt;Table of Contents&lt;/h4&gt;
 
-
 
-
&lt;ul&gt;
 
-
&lt;li&gt;&lt;a href="#basic"&gt;Basic statistics&lt;/a&gt;&lt;/li&gt;
 
-
 
-
&lt;li&gt;&lt;a href="#advanced"&gt;Advanced statistics&lt;/a&gt;&lt;/li&gt;
 
-
&lt;li&gt;&lt;a href="#intro"&gt;Introducing Newt&lt;/a&gt;&lt;/li&gt;
 
-
&lt;li&gt;&lt;a href="#charts"&gt;Working with charts&lt;/a&gt;&lt;/li&gt;
 
-
 
-
&lt;li&gt;&lt;a href="#pred"&gt;Predicting values&lt;/a&gt;&lt;/li&gt;
 
-
&lt;li&gt;&lt;a href="#neural"&gt;Neural networks&lt;/a&gt;&lt;/li&gt;
 
-
&lt;li&gt;&lt;a href="#glos"&gt;Glossary&lt;/a&gt;&lt;/li&gt;
 
-
 
-
&lt;/ul&gt;
 
-
 
-
&lt;p&gt;
 
-
&lt;a name="basic"&gt;
 
-
&lt;h6&gt;Basic Statistics&lt;/h6&gt;
 
-
Overview of elementary concepts in statistics.
 
-
Variables. Correlation. Measurement scales. Statistical significance.
 
-
Distributions. Normality assumption.
 
-
&lt;/a&gt;
 
-
&lt;/p&gt;
 
-
 
-
&lt;p&gt;
 
-
&lt;a name="advanced"&gt;
 
-
&lt;h6&gt;Advanced Statistics&lt;/h6&gt;
 
-
Overview of advanced concepts in statistics. Anova. Linear regression.
 
-
Estimation and  hypothesis testing.
 
-
Error terms.
 
-
&lt;/a&gt;
 
-
&lt;/p&gt;
 
-
 
-
&lt;p&gt;
 
-
&lt;a name="intro"&gt;
 
-
 
-
&lt;h6&gt;Introducing Newt&lt;/h6&gt;
 
-
Introducing the basic functionality of the Newt application. Creating sheets.
 
-
Charts. Menus and Toolbars. Importing data. Saving data in various formats.
 
-
Exporting data. Shortcuts. List of methods.
 
-
&lt;/a&gt;
 
-
&lt;/p&gt;
 
-
 
-
&lt;p&gt;
 
-
&lt;a name="charts"&gt;
 
-
&lt;h6&gt;Charts&lt;/h6&gt;
 
-
 
-
Working with charts. 2D charts. 3D charts. Bar, line, box, pie, range charts.
 
-
Scatterplots. Histograms.
 
-
&lt;/a&gt;
 
-
&lt;/p&gt;
 
-
 
-
&lt;p&gt;
 
-
&lt;a name="pred"&gt;
 
-
&lt;h6&gt;Predicting values&lt;/h6&gt;
 
-
Time series and forecasting. Trend Analysis. Seasonality. Moving averages.
 
-
Univariate methods. Multivariate methods. Holt-Winters smoothing.
 
-
Exponential smoothing. ARIMA. Fourier analysis.
 
-
&lt;/a&gt;
 
-
 
-
&lt;/p&gt;
 
-
 
-
&lt;p&gt;
 
-
&lt;a name="neural"&gt;
 
-
&lt;h6&gt;Neural networks&lt;/h6&gt;
 
-
Overview of neural networks. Biology behind neural networks.
 
-
Basic artificial Model. Training. Preprocessing. Postprocessing.
 
-
Types of neural networks.
 
-
&lt;/a&gt;
 
-
&lt;/p&gt;
 
-
 
-
&lt;p&gt;
 
-
&lt;a name="glos"&gt;
 
-
&lt;h6&gt;Glossary&lt;/h6&gt;
 
-
Terms and definitions in statistics.
 
-
&lt;/a&gt;
 
-
&lt;/p&gt;
 
-
 
-
&lt;/body&gt;
 
-
&lt;/html&gt;
 
-
 
-
</source>
 
-
 
-
<source lang="python">
 
-
&lt;li&gt;&lt;a href="#basic"&gt;Basic statistics&lt;/a&gt;&lt;/li&gt;
 
-
...
 
-
&lt;a name="basic"&gt;
 
-
</source>
 
-
 
-
Normally I would write &lt;div id="basic"&gt; ... &lt;/div&gt;. Both are correct html notations. But <i>wx.html.HtmlWindow</i> supports only the first one. <i>wx.html.HtmlWindow</i> supports only a subset of the html markup language.
 
-
 
-
[[image: wxPython_faq_helpwindow.png | center]]
 
-
 
-
== A wx.ListCtrl widget ==
 
-
A <i>wx.ListCtrl</i> is a graphical representation of a list of items. A <i>wx.ListBox</i> can only have one column. <i>wx.ListCtrl</i> can have more than one column.
 
-
 
-
<i>wx.ListCtrl</i> is a very common and useful widget.
 
-
For example a file manager uses a <i>wx.ListCtrl</i> to display directories and files on the file system. A cd burner application displays files to be burned inside a <i>wx.ListCtrl</i>.
 
-
 
-
A <i>wx.ListCtrl</i> can be used in three different formats. In a list view, report view or a icon view. These formats are controled by the <i>wx.ListCtrl</i> window styles. <i>wx.LC_REPORT</i>, <i>wx.LC_LIST</i> and <i>wx.LC_ICON</i>.
 
-
 
-
<source lang="python">
 
-
wx.ListCtrl(wx.Window parent, int id, wx.Point pos = (-1, -1), wx.Size size = (-1, -1),
 
-
int style = wx.LC_ICON, wx.Validator validator = wx.DefaultValidator, string name = wx.ListCtrlNameStr)
 
-
</source>
 
-
 
-
=== wx.ListCtrl styles ===
 
-
* 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
 
-
 
-
 
-
=== Simple example ===
 
-
 
-
In the first example we will introduce basic functionality of a <i>wx.ListCtrl</i>.
 
-
 
-
<source lang="python">
 
-
#!/usr/bin/python
 
-
# actresses.py
 
-
 
-
import wx
 
-
import sys
 
-
 
-
packages = [('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 Actresses(wx.Frame):
 
-
    def __init__(self, parent, id, title):
 
-
        wx.Frame.__init__(self, parent, id, title, size=(380, 230))
 
-
 
-
        hbox = wx.BoxSizer(wx.HORIZONTAL)
 
-
        panel = wx.Panel(self, -1)
 
-
 
-
        self.list = wx.ListCtrl(panel, -1, 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)
 
-
 
-
        for i in packages:
 
-
            index = self.list.InsertStringItem(sys.maxint, i[0])
 
-
            self.list.SetStringItem(index, 1, i[1])
 
-
            self.list.SetStringItem(index, 2, i[2])
 
-
 
-
        hbox.Add(self.list, 1, wx.EXPAND)
 
-
        panel.SetSizer(hbox)
 
-
 
-
        self.Centre()
 
-
        self.Show(True)
 
-
 
-
app = wx.App()
 
-
Actresses(None, -1, 'actresses')
 
-
app.MainLoop()
 
-
</source>
 
-
 
-
 
-
<source lang="python">
 
-
self.list = wx.ListCtrl(panel, -1, style=wx.LC_REPORT)
 
-
</source>
 
-
 
-
We create a <i>wx.ListCtrl</i> with a wx.LC_REPORT style.
 
-
 
-
<source lang="python">
 
-
self.list.InsertColumn(0, 'name', width=140)
 
-
self.list.InsertColumn(1, 'place', width=130)
 
-
self.list.InsertColumn(2, 'year', wx.LIST_FORMAT_RIGHT, 90)
 
-
</source>
 
-
 
-
We insert three columns. We can specify the <i>width</i> of the column and the <i>format</i> of the column. The default format is <i>wx.LIST_FORMAT_LEFT</i>.
 
-
 
-
<source lang="python">
 
-
for i in packages:
 
-
    index = self.list.InsertStringItem(sys.maxint, i[0])
 
-
    self.list.SetStringItem(index, 1, i[1])
 
-
    self.list.SetStringItem(index, 2, i[2])
 
-
</source>
 
-
 
-
We insert data into the <i>wx.ListCtrl</i> using two methods. Each row begins with a <i>InsertStringItem()</i> method. The first parameter of the method specifies the row number. By giving a sys.maxint we ensure, that each call will insert data after the last row. The method returns the row index. The <i>SetStringItem()</i> method adds data to the consecutive columns of the current row.
 
-
 
-
=== Mixins ===
 
-
Mixins are classes that further enhance the functionality of a <i>wx.ListCtrl</i>. Mixin classes are so called helper classes. They are located in <i>wx.lib.mixins.listctrl</i> module. In order to use them, the programmer has to inherit from these classes.
 
-
 
-
There are five available mixins. As of 2.8.1.1.
 
-
 
-
* wx.ColumnSorterMixin
 
-
* wx.ListCtrlAutoWidthMixin
 
-
* wx.ListCtrlSelectionManagerMix
 
-
* wx.TextEditMixin
 
-
* wx.CheckListCtrlMixin
 
-
 
-
<i>wx.ColumnSorterMixin</i> is a mixin that enables sorting of columns in a report view. <i>wx.ListCtrlAutoWidthMixin</i> class automatically resizes the last column to the end of the <i>wx.ListCtrl</i>. By default, the last column does not take the remaining space. See the previous example. <i>wx.ListCtrlSelectionManagerMix</i> defines platform independent selection policy. <i>wx.TextEditMixin</i> enables text to be edited. <i>wx.CheckListCtrlMixin</i> adds a check box to each row. This way we can control rows. We can set every row to be checked or unchecked.
 
-
 
-
The following code shows, how we can use <i>ListCtrlAutoWidthMixin</i>
 
-
<source lang="python">
 
-
#!/usr/bin/python
 
-
# autowidth.py
 
-
 
-
import wx
 
-
import sys
 
-
from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin
 
-
 
-
actresses = [('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, ListCtrlAutoWidthMixin):
 
-
    def __init__(self, parent):
 
-
        wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT)
 
-
        ListCtrlAutoWidthMixin.__init__(self)
 
-
 
-
 
-
class Actresses(wx.Frame):
 
-
    def __init__(self, parent, id, title):
 
-
        wx.Frame.__init__(self, parent, id, title, size=(380, 230))
 
-
 
-
        hbox = wx.BoxSizer(wx.HORIZONTAL)
 
-
 
-
        panel = wx.Panel(self, -1)
 
-
 
-
        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)
 
-
 
-
        for i in actresses:
 
-
            index = self.list.InsertStringItem(sys.maxint, i[0])
 
-
            self.list.SetStringItem(index, 1, i[1])
 
-
            self.list.SetStringItem(index, 2, i[2])
 
-
 
-
        hbox.Add(self.list, 1, wx.EXPAND)
 
-
        panel.SetSizer(hbox)
 
-
 
-
        self.Centre()
 
-
        self.Show(True)
 
-
 
-
app = wx.App()
 
-
Actresses(None, -1, 'actresses')
 
-
app.MainLoop()
 
-
</source>
 
-
 
-
We change the previous example a bit.
 
-
<source lang="python">
 
-
from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin
 
-
</source>
 
-
 
-
Here we import the mixin.
 
-
 
-
 
-
<source lang="python">
 
-
class AutoWidthListCtrl(wx.ListCtrl, ListCtrlAutoWidthMixin):
 
-
    def __init__(self, parent):
 
-
        wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT)
 
-
        ListCtrlAutoWidthMixin.__init__(self)
 
-
</source>
 
-
 
-
We create a new <i>AutoWidthListCtrl</i> class. This class will inherit from <i>wx.ListCtrl</i> and <i>ListCtrlAutoWidthMixin</i>. This is called <b>multiple inheritance</b>.
 
-
The last column will automatically resize to take up the remaining width of a <i>wx.ListCtrl</i>.
 
-
 
-
<center>[[image: wxPython_faq_autowidthl.jpg | center]] [[image: wxPython_faq_autowidthw.jpg | center]]</center>
 
-
 
-
In the following example we will show, how we can create sortable columns. If we click on the column header, the corresponding rows in a column are sorted.
 
-
 
-
<source lang="python">
 
-
#!/usr/bin/python
 
-
# sorted.py
 
-
 
-
import wx
 
-
import sys
 
-
from wx.lib.mixins.listctrl import ColumnSorterMixin
 
-
 
-
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, ColumnSorterMixin):
 
-
    def __init__(self, parent):
 
-
        wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT)
 
-
        ColumnSorterMixin.__init__(self, len(actresses))
 
-
        self.itemDataMap = actresses
 
-
 
-
    def GetListCtrl(self):
 
-
        return self
 
-
 
-
class Actresses(wx.Frame):
 
-
    def __init__(self, parent, id, title):
 
-
        wx.Frame.__init__(self, parent, id, title, size=(380, 230))
 
-
 
-
        hbox = wx.BoxSizer(wx.HORIZONTAL)
 
-
 
-
        panel = wx.Panel(self, -1)
 
-
 
-
        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()
 
-
 
-
        for key, data in items:
 
-
            index = self.list.InsertStringItem(sys.maxint, data[0])
 
-
            self.list.SetStringItem(index, 1, data[1])
 
-
            self.list.SetStringItem(index, 2, data[2])
 
-
            self.list.SetItemData(index, key)
 
-
 
-
        hbox.Add(self.list, 1, wx.EXPAND)
 
-
        panel.SetSizer(hbox)
 
-
 
-
        self.Centre()
 
-
        self.Show(True)
 
-
 
-
app = wx.App()
 
-
Actresses(None, -1, 'actresses')
 
-
app.MainLoop()
 
-
</source>
 
-
 
-
We will again use the example with actresses.
 
-
 
-
<source lang="python">
 
-
ColumnSorterMixin.__init__(self, len(actresses))
 
-
</source>
 
-
 
-
The <i>ColumnSorterMixin</i> accepts one argument. It is the number of columns to be sorted.
 
-
 
-
<source lang="python">
 
-
 
-
self.itemDataMap = actresses
 
-
</source>
 
-
 
-
We must map our data to be displayed in a list control to the <i>itemDataMap</i> attribute. The data must be in a dictionary data type.
 
-
 
-
<source lang="python">
 
-
def GetListCtrl(self):
 
-
    return self
 
-
</source>
 
-
 
-
We must create a <i>GetListCtrl()</i> method. This method returns the <i>wx.ListCtrl</i> widget that is going to be sorted.
 
-
 
-
<source lang="python">
 
-
self.list.SetItemData(index, key)
 
-
</source>
 
-
 
-
We must assosiate each row with a special index. This is done with the <i>SetItemData</i> method.
 
-
 
-
=== Reader ===
 
-
A reader is a complex example showing two list controls in a report view.
 
-
<source lang="python">
 
-
#!/usr/bin/python
 
-
# reader.py
 
-
 
-
 
-
import wx
 
-
 
-
articles = [['Mozilla rocks', 'The year of the Mozilla', 'Earth on Fire'],
 
-
            ['Gnome pretty, Gnome Slow', 'Gnome, KDE, Icewm, XFCE', 'Where is Gnome heading?'],
 
-
            ['Java number one language', 'Compiled languages, intrepreted Languages', 'Java on Desktop?']]
 
-
 
-
 
-
 
-
class ListCtrlLeft(wx.ListCtrl):
 
-
    def __init__(self, parent, id):
 
-
        wx.ListCtrl.__init__(self, parent, id, style=wx.LC_REPORT | wx.LC_HRULES |
 
-
wx.LC_NO_HEADER | wx.LC_SINGLE_SEL)
 
-
        images = ['icons/java.png', 'icons/gnome.png', 'icons/mozilla.png']
 
-
 
-
        self.parent = parent
 
-
 
-
        self.Bind(wx.EVT_SIZE, self.OnSize)
 
-
        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnSelect)
 
-
 
-
        self.il = wx.ImageList(32, 32)
 
-
        for i in images:
 
-
            self.il.Add(wx.Bitmap(i))
 
-
 
-
        self.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
 
-
        self.InsertColumn(0, '')
 
-
 
-
        for i in range(3):
 
-
            self.InsertStringItem(0, '')
 
-
            self.SetItemImage(0, i)
 
-
 
-
    def OnSize(self, event):
 
-
        size = self.parent.GetSize()
 
-
        self.SetColumnWidth(0, size.x-5)
 
-
        event.Skip()
 
-
 
-
    def OnSelect(self, event):
 
-
        window = self.parent.GetGrandParent().FindWindowByName('ListControlOnRight')
 
-
        index = event.GetIndex()
 
-
        window.LoadData(index)
 
-
 
-
    def OnDeSelect(self, event):
 
-
        index = event.GetIndex()
 
-
        self.SetItemBackgroundColour(index, 'WHITE')
 
-
 
-
    def OnFocus(self, event):
 
-
        self.SetItemBackgroundColour(0, 'red')
 
-
 
-
class ListCtrlRight(wx.ListCtrl):
 
-
    def __init__(self, parent, id):
 
-
        wx.ListCtrl.__init__(self, parent, id, style=wx.LC_REPORT | wx.LC_HRULES |
 
-
wx.LC_NO_HEADER | wx.LC_SINGLE_SEL)
 
-
 
-
        self.parent = parent
 
-
 
-
        self.Bind(wx.EVT_SIZE, self.OnSize)
 
-
 
-
        self.InsertColumn(0, '')
 
-
 
-
 
-
    def OnSize(self, event):
 
-
        size = self.parent.GetSize()
 
-
        self.SetColumnWidth(0, size.x-5)
 
-
        event.Skip()
 
-
 
-
    def LoadData(self, index):
 
-
        self.DeleteAllItems()
 
-
        for i in range(3):
 
-
            self.InsertStringItem(0, articles[index][i])
 
-
 
-
 
-
class Reader(wx.Frame):
 
-
    def __init__(self, parent, id, title):
 
-
        wx.Frame.__init__(self, parent, id, title)
 
-
 
-
        hbox = wx.BoxSizer(wx.HORIZONTAL)
 
-
        splitter = wx.SplitterWindow(self, -1, style=wx.SP_LIVE_UPDATE|wx.SP_NOBORDER)
 
-
 
-
        vbox1 = wx.BoxSizer(wx.VERTICAL)
 
-
        panel1 = wx.Panel(splitter, -1)
 
-
        panel11 = wx.Panel(panel1, -1, size=(-1, 40))
 
-
        panel11.SetBackgroundColour('#53728c')
 
-
        st1 = wx.StaticText(panel11, -1, 'Feeds', (5, 5))
 
-
        st1.SetForegroundColour('WHITE')
 
-
 
-
        panel12 = wx.Panel(panel1, -1, style=wx.BORDER_SUNKEN)
 
-
        vbox = wx.BoxSizer(wx.VERTICAL)
 
-
        list1 = ListCtrlLeft(panel12, -1)
 
-
 
-
        vbox.Add(list1, 1, wx.EXPAND)
 
-
        panel12.SetSizer(vbox)
 
-
        panel12.SetBackgroundColour('WHITE')
 
-
 
-
 
-
        vbox1.Add(panel11, 0, wx.EXPAND)
 
-
        vbox1.Add(panel12, 1, wx.EXPAND)
 
-
 
-
        panel1.SetSizer(vbox1)
 
-
 
-
        vbox2 = wx.BoxSizer(wx.VERTICAL)
 
-
        panel2 = wx.Panel(splitter, -1)
 
-
        panel21 = wx.Panel(panel2, -1, size=(-1, 40), style=wx.NO_BORDER)
 
-
        st2 = wx.StaticText(panel21, -1, 'Articles', (5, 5))
 
-
        st2.SetForegroundColour('WHITE')
 
-
 
-
        panel21.SetBackgroundColour('#53728c')
 
-
        panel22 = wx.Panel(panel2, -1, style=wx.BORDER_RAISED)
 
-
        vbox3 = wx.BoxSizer(wx.VERTICAL)
 
-
        list2 = ListCtrlRight(panel22, -1)
 
-
        list2.SetName('ListControlOnRight')
 
-
        vbox3.Add(list2, 1, wx.EXPAND)
 
-
        panel22.SetSizer(vbox3)
 
-
 
-
 
-
        panel22.SetBackgroundColour('WHITE')
 
-
        vbox2.Add(panel21, 0, wx.EXPAND)
 
-
        vbox2.Add(panel22, 1, wx.EXPAND)
 
-
 
-
        panel2.SetSizer(vbox2)
 
-
 
-
        toolbar = self.CreateToolBar()
 
-
        toolbar.AddLabelTool(1, 'Exit', wx.Bitmap('icons/stock_exit.png'))
 
-
        toolbar.Realize()
 
-
 
-
        self.Bind(wx.EVT_TOOL, self.ExitApp, id=1)
 
-
 
-
        hbox.Add(splitter, 1, wx.EXPAND | wx.TOP | wx.BOTTOM, 5)
 
-
        self.SetSizer(hbox)
 
-
        self.CreateStatusBar()
 
-
        splitter.SplitVertically(panel1, panel2)
 
-
        self.Centre()
 
-
        self.Show(True)
 
-
 
-
 
-
    def ExitApp(self, event):
 
-
        self.Close()
 
-
 
-
 
-
app = wx.App()
 
-
Reader(None, -1, 'Reader')
 
-
app.MainLoop()
 
-
</source>
 
-
 
-
The previous example showed a <i>wx.ListCtrl</i> in a report view. With no headers. We shall create our own headers. We show two <i>wx.ListCtrl</i> widgets. One is on the right side and the other one on the left side of the application.
 
-
 
-
<source lang="python">
 
-
splitter = wx.SplitterWindow(self, -1, style=wx.SP_LIVE_UPDATE|wx.SP_NOBORDER)
 
-
...
 
-
splitter.SplitVertically(panel1, panel2)
 
-
</source>
 
-
 
-
The splitter will split the main window into two vertical parts. The splitter will show two panels. Those two panels will have another  two panels. They create <i>Feeds</i> and <i>Articles</i> headers. The rest of the space will be occupied by our two <i>wx.ListCtrl</i> widgets.
 
-
 
-
<source lang="python">
 
-
list2 = ListCtrlRight(panel22, -1)
 
-
list2.SetName('ListControlOnRight')
 
-
</source>
 
-
 
-
When we create <i>ListCtrlRight</i> object, we  give it a name <i>ListControlOnRight</i>. This is because we need <i>ListCtrlRight</i>  and <i>ListCtrlLeft</i> two widgets to communicate.
 
-
 
-
<source lang="python">
 
-
def OnSelect(self, event):
 
-
    window = self.parent.GetGrandParent().FindWindowByName('ListControlOnRight')
 
-
    index = event.GetIndex()
 
-
    window.LoadData(index)
 
-
</source>
 
-
 
-
This code is in  <i>ListCtrlLeft</i> class. Here we locate the <i>ListCtrlRight</i> object and call it's <i>LoadData()</i> method.
 
-
 
-
<source lang="python">
 
-
def LoadData(self, index):
 
-
    self.DeleteAllItems()
 
-
    for i in range(3):
 
-
        self.InsertStringItem(0, articles[index][i])
 
-
</source>
 
-
 
-
The <i>LoadData()</i> method first clears all items. Then it inserts the article names from the globally defined articles list. The index has been passed.
 
-
 
-
<source lang="python">
 
-
def OnSize(self, event):
 
-
    size = self.parent.GetSize()
 
-
    self.SetColumnWidth(0, size.x-5)
 
-
    event.Skip()
 
-
 
-
</source>
 
-
 
-
Both <i>wx.ListCtrl</i>s have only one column. Here we ensure that the size of the column equals to size of the parent panel.
 
-
The application would not look nice otherwise. Why do we extract 5px? This number is a kind of magic number. If we extract exactly 5px, the horizotal scrollbars do not appear. On other platforms, the number might be different.
 
-
 
-
[[image: wxPython_faq_reader.png | center]]
 
-
 
-
=== CheckListCtrl ===
 
-
 
-
It is quite common to see applications having check boxes inside list controls. For example a packaging application like Synaptic or KYUM.
 
-
 
-
From the programmer's point of view, those checkboxes are simple images. There are two states. Checked and unchecked. For both situations we have a unique image. We do not have to implement the functionality. It has been already coded. The code is in <i>CheckListCtrlMixin</i>.
 
-
 
-
<source lang="python">
 
-
#!/usr/bin/python
 
-
# repository.py
 
-
 
-
import wx
 
-
import sys
 
-
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, -1, style=wx.LC_REPORT | wx.SUNKEN_BORDER)
 
-
        CheckListCtrlMixin.__init__(self)
 
-
        ListCtrlAutoWidthMixin.__init__(self)
 
-
 
-
 
-
class Repository(wx.Frame):
 
-
    def __init__(self, parent, id, title):
 
-
        wx.Frame.__init__(self, parent, id, title, size=(450, 400))
 
-
 
-
        panel = wx.Panel(self, -1)
 
-
 
-
        vbox = wx.BoxSizer(wx.VERTICAL)
 
-
        hbox = wx.BoxSizer(wx.HORIZONTAL)
 
-
 
-
        leftPanel = wx.Panel(panel, -1)
 
-
        rightPanel = wx.Panel(panel, -1)
 
-
 
-
        self.log = wx.TextCtrl(rightPanel, -1, style=wx.TE_MULTILINE)
 
-
        self.list = CheckListCtrl(rightPanel)
 
-
        self.list.InsertColumn(0, 'Package', width=140)
 
-
        self.list.InsertColumn(1, 'Size')
 
-
        self.list.InsertColumn(2, 'Repository')
 
-
 
-
        for i in packages:
 
-
            index = self.list.InsertStringItem(sys.maxint, i[0])
 
-
            self.list.SetStringItem(index, 1, i[1])
 
-
            self.list.SetStringItem(index, 2, i[2])
 
-
 
-
        vbox2 = wx.BoxSizer(wx.VERTICAL)
 
-
 
-
        sel = wx.Button(leftPanel, -1, 'Select All', size=(100, -1))
 
-
        des = wx.Button(leftPanel, -1, 'Deselect All', size=(100, -1))
 
-
        apply = wx.Button(leftPanel, -1, 'Apply', size=(100, -1))
 
-
 
-
 
-
        self.Bind(wx.EVT_BUTTON, self.OnSelectAll, id=sel.GetId())
 
-
        self.Bind(wx.EVT_BUTTON, self.OnDeselectAll, id=des.GetId())
 
-
        self.Bind(wx.EVT_BUTTON, self.OnApply, id=apply.GetId())
 
-
 
-
        vbox2.Add(sel, 0, wx.TOP, 5)
 
-
        vbox2.Add(des)
 
-
        vbox2.Add(apply)
 
-
 
-
        leftPanel.SetSizer(vbox2)
 
-
 
-
        vbox.Add(self.list, 1, wx.EXPAND | wx.TOP, 3)
 
-
        vbox.Add((-1, 10))
 
-
        vbox.Add(self.log, 0.5, 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.Centre()
 
-
        self.Show(True)
 
-
 
-
    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')
 
-
 
-
app = wx.App()
 
-
Repository(None, -1, 'Repository')
 
-
app.MainLoop()
 
-
</source>
 
-
 
-
[[image: wxPython_faq_repository.png | center]]
 
-
 
-
<source lang="python">
 
-
class CheckListCtrl(wx.ListCtrl, CheckListCtrlMixin, ListCtrlAutoWidthMixin):
 
-
    def __init__(self, parent):
 
-
        wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT | wx.SUNKEN_BORDER)
 
-
        CheckListCtrlMixin.__init__(self)
 
-
        ListCtrlAutoWidthMixin.__init__(self)
 
-
</source>
 
-
 
-
wxPython enables multiple inheritance. Here we inherit from three different classes.
 
-
 
-
<source lang="python">
 
-
def OnSelectAll(self, event):
 
-
    num = self.list.GetItemCount()
 
-
    for i in range(num):
 
-
        self.list.CheckItem(i)
 
-
 
-
</source>
 
-
 
-
Here we can see multiple inheritance in action. We can call two methods from two different classes on our <i>self.list</i> object. The <i>GetItemCount()</i> method is located in <i>CheckListCtrl</i> class and the <i>CheckItem()</i> method is in <i> CheckListCtrlMixin</i> class.
 
-
 
-
[[Категория:wxWidgets]]
 
-
[[Категория:Python]]
 

Текущая версия на 12:00, 7 апреля 2009