# wxPython 中的高级小部件
> 原文: [http://zetcode.com/wxpython/advanced/](http://zetcode.com/wxpython/advanced/)
在本章中,我们讨论以下高级小部件:`wx.ListBox`,`wx.html.HtmlWindow`和`wx.ListCtrl`。
wxPython 有几个众所周知的高级小部件。 例如,树小部件,HTML 窗口,网格小部件,列表框小部件,列表小部件或具有高级样式功能的编辑器。
## `wx.ListBox`小部件
`wx.ListBox`用于显示和使用项目列表。 可以在两种不同的状态下创建`wx.ListBox`:处于单选状态或多选状态。 单一选择状态是默认状态。
`wx.ListBox`中有两个重要事件。 第一个是`wx.EVT_COMMAND_LISTBOX_SELECTED`事件。 当我们在`wx.ListBox`中选择一个项目时,将生成此事件。 第二个事件是`wx.EVT_COMMAND_LISTBOX_DOUBLE_CLICKED`事件。 当我们双击`wx.ListBox`中的项目时会生成该文件。 元素从零开始编号。 如果需要,滚动条会自动显示。
`listbox.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
ZetCode wxPython tutorial
In this example, we create a wx.ListBox widget.
author: Jan Bodnar
website: www.zetcode.com
last modified: May 2018
"""
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()
```
该示例显示了如何从`wx.ListBox`添加,修改和删除项目。
```py
self.listbox = wx.ListBox(panel)
hbox.Add(self.listbox, wx.ID_ANY, wx.EXPAND | wx.ALL, 20)
```
我们创建一个空的`wx.ListBox`。 我们在列表框周围放置了 20px 的边框。
```py
self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRename)
```
我们使用`wx.EVT_LISTBOX_DCLICK`事件绑定器将`wx.EVT_COMMAND_LISTBOX_DOUBLE_CLICKED`事件类型与`OnRename()`方法绑定。 这样,如果我们双击列表框中的特定元素,我们将显示一个重命名对话框。
```py
def NewItem(self, event):
text = wx.GetTextFromUser('Enter a new item', 'Insert dialog')
if text != '':
self.listbox.Append(text)
```
我们通过单击“新建”按钮来调用`NewItem()`方法。 此方法使用包装器`wx.GetTextFromUser()`方法显示`wx.TextEntryDialog`。 我们输入的文本将返回到`text`变量。 如果文本不为空,则使用`Append()`方法将其附加到列表框。
```py
if renamed != '':
self.listbox.Delete(sel)
item_id = self.listbox.Insert(renamed, sel)
self.listbox.SetSelection(item_id)
```
我们通过删除项目并在同一位置插入新项目来重命名该项目。 我们还将选择重新设置为修改后的项目。
```py
def OnDelete(self, event):
sel = self.listbox.GetSelection()
if sel != -1:
self.listbox.Delete(sel)
```
要删除项目,我们通过调用`GetSelection()`方法找到所选项目的索引。 然后,我们使用`Delete()`方法删除该项目。 `Delete()`方法的参数是所选索引。
```py
def OnClear(self, event):
self.listbox.Clear()
```
最简单的方法是清除整个列表框。 我们只需调用`Clear()`方法。
![wx.ListBox widget](https://img.kancloud.cn/dd/71/dd71b4975361a8fc86942635c5e3c4aa_400x250.jpg)
图:`wx.ListBox`小部件
## `wx.html.HtmlWindow`小部件
`wx.html.HtmlWindow`小部件显示 HTML 页面。 它不是完整的浏览器。 我们可以使用`wx.html.HtmlWindow`小部件来做一些有趣的事情。
例如,在下面的程序中,我们创建一个显示基本统计信息的窗口。
`page.html`
```py
<!DOCTYPE html>
<html>
<body bgcolor="#8e8e95">
<table cellspacing="5" border="0" width="250">
<tr width="200" align="left">
<td bgcolor="#e7e7e7"> Maximum</td>
<td bgcolor="#aaaaaa"> <b>9000</b></td>
</tr>
<tr align="left">
<td bgcolor="#e7e7e7"> Mean</td>
<td bgcolor="#aaaaaa"> <b>6076</b></td>
</tr>
<tr align="left">
<td bgcolor="#e7e7e7"> Minimum</td>
<td bgcolor="#aaaaaa"> <b>3800</b></td>
</tr>
<tr align="left">
<td bgcolor="#e7e7e7"> Median</td>
<td bgcolor="#aaaaaa"> <b>6000</b></td>
</tr>
<tr align="left">
<td bgcolor="#e7e7e7"> Standard Deviation</td>
<td bgcolor="#aaaaaa"> <b>6076</b></td>
</tr>
</table>
</body>
</html>
```
这是要显示的 HTML 页面。
`htmlwin.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
ZetCode wxPython tutorial
In this example, we create a wx.html.HtmlWindow widget.
author: Jan Bodnar
website: www.zetcode.com
last modified: May 2018
"""
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('newt.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 | wx.ALIGN_RIGHT)
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()
```
该示例在`wx.html.HtmlWindow`小部件中分配 HTML 文件。
```py
htmlwin = wx.html.HtmlWindow(panel, wx.ID_ANY, style=wx.NO_BORDER)
htmlwin.SetStandardFonts()
htmlwin.LoadPage("page.html")
```
`wx.html.HtmlWindow`已创建。 HTML 文件使用`LoadPage()`方法加载。
![](https://img.kancloud.cn/c7/d2/c7d260ecae024579e17f6025b2da3458_427x293.jpg)
图:`wx.html.HtmlWindow`示例
## 帮助窗口
我们可以使用`wx.html.HtmlWindow`在我们的应用中提供帮助。 我们可以创建一个独立的窗口,也可以创建将成为应用一部分的窗口。 以下脚本将使用后一种想法创建一个帮助窗口。
`helpwindow.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
ZetCode wxPython tutorial
In this example, we create a help window window
with wx.html.HtmlWindow.
author: Jan Bodnar
website: www.zetcode.com
last modified: May 2018
"""
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('exit.png'))
toolbar.AddTool(2, 'Help', wx.Bitmap('help.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('closebutton.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('help.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()
```
帮助窗口一开始是隐藏的。 我们可以通过点击工具栏上的帮助按钮或按 `F1` 表现出来。 帮助窗口出现在应用的右侧。 要隐藏的帮助窗口,我们点击关闭按钮。
```py
self.splitter.SplitVertically(self.panelLeft, self.panelRight)
self.splitter.Unsplit()
```
我们创建左面板和右面板并将其垂直拆分。 之后,我们调用`Unsplit()`方法。 默认情况下,该方法隐藏右侧或底部窗格。
我们将右侧面板分为两部分。 面板的标题和主体。 标头是已调整的`wx.Panel`。 标题由静态文本和位图按钮组成。 我们将`wx.html.Window`放入面板的主体中。
```py
closeBtn = wx.BitmapButton(header, wx.ID_ANY, wx.Bitmap('closebutton.png',
wx.BITMAP_TYPE_PNG), style=wx.NO_BORDER)
closeBtn.SetBackgroundColour('#6f6a59')
```
位图按钮样式设置为`wx.NO_BORDER`。 背景颜色设置为标题面板的颜色。 这样做是为了使按钮显示为标题的一部分。
```py
helpWin = html.HtmlWindow(self.panelRight, style=wx.NO_BORDER)
helpWin.LoadPage('help.html')
```
我们在右侧面板上创建一个`wx.html.HtmlWindow`小部件。 我们的 HTML 代码位于单独的文件中。 这次我们调用`LoadPage()`方法来获取 HTML 代码。
```py
self.panelLeft.Bind(wx.EVT_KEY_DOWN, self.OnKeyPressed)
self.panelLeft.SetFocus()
```
我们将重点放在左侧面板上。 我们可以使用`F1`键启动帮助窗口。 为了使用键盘控制窗口,必须具有焦点。 如果未设置焦点,则必须首先单击面板,然后才能通过按 `F1` 键启动帮助窗口。
```py
def OnHelp(self, e):
self.splitter.SplitVertically(self.panelLeft, self.panelRight)
self.panelLeft.SetFocus()
```
为了显示帮助窗口,我们调用`OnHelp()`方法。 它将垂直拆分两个面板。 我们一定不要忘记再次设置焦点,因为初始焦点会因拆分而丢失。
以下是我们在应用中加载的 HTML 文件。
`help.html`
```py
<!DOCTYPE html>
<html>
<body bgcolor="#ababab">
<h4>Table of Contents</h4>
<ul>
<li><a href="#basic">Basic statistics</a></li>
<li><a href="#advanced">Advanced statistics</a></li>
<li><a href="#intro">Introducing Newt</a></li>
<li><a href="#charts">Working with charts</a></li>
<li><a href="#pred">Predicting values</a></li>
<li><a href="#neural">Neural networks</a></li>
<li><a href="#glos">Glossary</a></li>
</ul>
<p>
<a name="basic">
<h6>Basic Statistics</h6>
Overview of elementary concepts in statistics.
Variables. Correlation. Measurement scales. Statistical significance.
Distributions. Normality assumption.
</a>
</p>
<p>
<a name="advanced">
<h6>Advanced Statistics</h6>
Overview of advanced concepts in statistics. Anova. Linear regression.
Estimation and hypothesis testing.
Error terms.
</a>
</p>
<p>
<a name="intro">
<h6>Introducing Newt</h6>
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.
</a>
</p>
<p>
<a name="charts">
<h6>Charts</h6>
Working with charts. 2D charts. 3D charts. Bar, line, box, pie, range charts.
Scatterplots. Histograms.
</a>
</p>
<p>
<a name="pred">
<h6>Predicting values</h6>
Time series and forecasting. Trend Analysis. Seasonality. Moving averages.
Univariate methods. Multivariate methods. Holt-Winters smoothing.
Exponential smoothing. ARIMA. Fourier analysis.
</a>
</p>
<p>
<a name="neural">
<h6>Neural networks</h6>
Overview of neural networks. Biology behind neural networks.
Basic artificial Model. Training. Preprocessing. Postprocessing.
Types of neural networks.
</a>
</p>
<p>
<a name="glos">
<h6>Glossary</h6>
Terms and definitions in statistics.
</a>
</p>
</body>
</html>
```
HTML 文件包含应用帮助的目录。
![](https://img.kancloud.cn/4b/14/4b143b4efcaf84f665db5c69b90e2180_580x372.jpg)
图:帮助窗口
## `wx.ListCtrl`小部件
`wx.ListCtrl`是项目列表的图形表示。 一个`wx.ListBox`只能有一列。 `wx.ListCtrl`可以有多个栏。 `wx.ListCtrl`是一个非常常见且有用的小部件。 例如,文件管理器使用`wx.ListCtrl`在文件系统上显示目录和文件。 cd 刻录机应用显示要在`wx.ListCtrl`中刻录的文件。
`wx.ListCtrl`可以三种不同的格式使用。 在列表视图,报告视图或图标视图中。 这些格式由`wx.ListCtrl`窗口样式控制。 `wx.LC_REPORT`,`wx.LC_LIST`和`wx.LC_ICON`。
## `wx.ListCtrl`样式
* `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`的一些基本功能。
`actresses.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
ZetCode wxPython tutorial
In this example, we create a simple
wx.ListCtrl widget.
author: Jan Bodnar
website: www.zetcode.com
last modified: May 2018
"""
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()
```
该代码示例在`wx.ListCtrl`中显示有关女演员的数据。
```py
self.list = wx.ListCtrl(panel, wx.ID_ANY, style=wx.LC_REPORT)
```
我们用`wx.LC_REPORT`样式创建一个`wx.ListCtrl`。
```py
self.list.InsertColumn(0, 'name', width=140)
self.list.InsertColumn(1, 'place', width=130)
self.list.InsertColumn(2, 'year', wx.LIST_FORMAT_RIGHT, 90)
```
我们插入三列。 我们可以指定列的`width`和列的`format`。 默认格式为`wx.LIST_FORMAT_LEFT`。
```py
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
```
我们使用两种方法将数据插入`wx.ListCtrl`。 每行以`InsertItem()`方法开头。 方法的第一个参数指定行号。 该方法返回行索引。 `SetItem()`方法将数据添加到当前行的连续列中。
### Mixin
Mixins 是进一步增强`wx.ListCtrl`函数的类。 它们位于`wx.lib.mixins.listctrl`模块中。 为了使用它们,我们必须从这些类继承。
有六个 mixin:
* `wx.ColumnSorterMixin`
* `wx.ListCtrlAutoWidthMixin`
* `wx.ListCtrlSelectionManagerMix`
* `wx.TextEditMixin`
* `wx.CheckListCtrlMixin`
* `wx.ListRowHighlighter`
`wx.ColumnSorterMixin`是一个混合器,可以对报表视图中的列进行排序。 `wx.ListCtrlAutoWidthMixin`类自动将最后一列的大小调整为`wx.ListCtrl`的末尾。 默认情况下,最后一列不占用剩余空间。 请参阅前面的示例。 `wx.ListCtrlSelectionManagerMix`定义了平台无关的选择策略。 `wx.TextEditMixin`可以编辑文本。 `wx.CheckListCtrlMixin`向每行添加一个复选框。 这样我们可以控制行。 我们可以将每一行设置为选中或取消选中。 `wx.ListRowHighlighter`处理`wx.ListCtrl`中交替行的自动背景突出显示。
### `wx.lib.mixins.listctrl.ListCtrlAutoWidthMixin`
以下代码显示了如何使用`wx.lib.mixins.listctrl.ListCtrlAutoWidthMixin`
`autowidth.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
ZetCode wxPython tutorial
In this example, we use wx.lib.mixins.listctrl.ListCtrlAutoWidthMixin
with a wx.ListBox.
author: Jan Bodnar
website: www.zetcode.com
last modified: May 2018
"""
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()
```
我们稍微改变前面的示例。
```py
import wx.lib.mixins.listctrl
```
在这里,我们导入 mixin 模块。
```py
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)
```
我们创建一个新的`AutoWidthListCtrl`类。 此类从`wx.ListCtrl`和`wx.lib.mixins.listctrl.ListCtrlAutoWidthMixin`继承。 这称为多重继承。 最后一列将自动调整大小以占据`wx.ListCtrl`的剩余宽度。
### `wx.lib.mixins.listctrl.ColumnSorterMixin`
以下示例创建可排序的列。 如果单击列标题,则会对列中的相应行进行排序。
`sorted.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
ZetCode wxPython tutorial
In this example, we create sortable columns with
wx.lib.mixins.listctrl.ColumnSorterMixin
author: Jan Bodnar
website: www.zetcode.com
last modified: May 2018
"""
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()
```
我们将再次在女演员中使用该示例。
```py
wx.lib.mixins.listctrl.ColumnSorterMixin.__init__(self, len(actresses))
```
`wx.lib.mixins.listctrl.ColumnSorterMixin`接受一个参数:要排序的列数。
```py
self.itemDataMap = actresses
```
我们必须将要显示在列表控件中的数据映射到`itemDataMap`属性。 数据必须为字典数据类型。
```py
def GetListCtrl(self):
return self
```
我们必须创建一个`GetListCtrl()`方法。 此方法返回将要排序的`wx.ListCtrl`小部件。
```py
self.list.SetItemData(index, key)
```
我们必须将每行与一个特殊索引相关联。 这是通过`SetItemData`方法完成的。
## `wx.lib.mixins.listctrl.CheckListCtrl`
可以在列表控件内放置一个复选框。 在 wxPython 中,我们可以使用`wx.lib.mixins.listctrl.CheckListCtrl`。
`repository.py`
```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
ZetCode wxPython tutorial
In this example, we create a check list control widget.
author: Jan Bodnar
website: www.zetcode.com
last modified: May 2018
"""
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()
```
该示例使用`wx.lib.mixins.listctrl.CheckListCtrl`创建仓库 UI。
```py
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)
```
我们从三个不同的类继承。
```py
def OnSelectAll(self, event):
num = self.list.GetItemCount()
for i in range(num):
self.list.CheckItem(i)
```
`OnSelectAll()`方法选择所有复选框。 `GetItemCount()`确定项目数,`CheckItem()`方法标记当前复选框。
![](https://img.kancloud.cn/58/2f/582f485dca6b19cdc354013fa188a0ce_595x392.jpg)
图:存储库
在 wxPython 教程的这一部分中,我们介绍了几个高级小部件,包括`wx.ListBox`,`wx.html.HtmlWindow`和`wx.ListCtrl`。
- ZetCode 数据库教程
- MySQL 教程
- MySQL 简介
- MySQL 安装
- MySQL 的第一步
- MySQL 快速教程
- MySQL 存储引擎
- MySQL 数据类型
- 在 MySQL 中创建,更改和删除表
- MySQL 表达式
- 在 MySQL 中插入,更新和删除数据
- MySQL 中的SELECT语句
- MySQL 子查询
- MySQL 约束
- 在 MySQL 中导出和导入数据
- 在 MySQL 中连接表
- MySQL 函数
- MySQL 中的视图
- MySQL 中的事务
- MySQL 存储过程
- MySQL Python 教程
- MySQL Perl 教程
- MySQL & Perl DBI
- 使用 Perl 连接到 MySQL 数据库
- MySQL 中的 Perl 错误处理
- 使用 Perl 进行 MySQL 查询
- 在 MySQL 中使用 Perl 绑定参数&列
- 在 MySQL 中使用 Perl 处理图像
- 使用 Perl 获取 MySQL 元数据
- Perl 的 MySQL 事务
- MySQL C API 编程教程
- MySQL Visual Basic 教程
- MySQL PHP 教程
- MySQL Java 教程
- MySQL Ruby 教程
- MySQL C# 教程
- SQLite 教程
- SQLite 简介
- sqlite3 命令行工具
- 在 SQLite 中创建,删除和更改表
- SQLite 表达式
- SQLite 插入,更新,删除数据
- SQLite SELECT语句
- SQLite 约束
- SQLite 连接表
- SQLite 函数
- SQLite 视图,触发器,事务
- SQLite C 教程
- SQLite Python 教程
- SQLite Perl 教程
- Perl DBI
- 使用 Perl 连接到 SQLite 数据库
- SQLite Perl 错误处理
- 使用 Perl 的 SQLite 查询
- 使用 Perl 绑定 SQLite 参数&列
- 使用 Perl 在 SQLite 中处理图像
- 使用 Perl 获取 SQLite 元数据
- 使用 Perl 进行 SQLite 事务
- SQLite Ruby 教程
- 连接到 SQLite 数据库
- 在 SQLite 中使用 Ruby 进行 SQL 查询
- 绑定参数
- 处理图像
- 使用 Ruby 获取 SQLite 元数据
- Ruby 的 SQLite 事务
- SQLite C# 教程
- SQLite C# 简介
- 使用SqliteDataReader检索数据
- ADO.NET 数据集
- 使用 C# 在 SQLite 中处理图像
- 使用 C# 获取 SQLite 元数据
- 使用 C# 的 SQLite 事务
- SQLite Visual Basic 教程
- SQLite Visual Basic 简介
- 使用SqliteDataReader检索数据
- ADO.NET 的数据集
- 使用 Visual Basic 在 SQLite 中处理图像
- 使用 Visual Basic 获取 SQLite 元数据
- 使用 Visual Basic 的 SQLite 事务
- PostgreSQL C 教程
- PostgreSQL Ruby 教程
- PostgreSQL PHP 教程
- PostgreSQL PHP 编程简介
- 在 PostgreSQL 中使用 PHP 检索数据
- 在 PostgreSQL 中使用 PHP 处理图像
- 用 PHP 获取 PostgreSQL 元数据
- 在 PostgreSQL 中使用 PHP 进行事务
- PostgreSQL Java 教程
- Apache Derby 教程
- Derby 简介
- Derby 的安装&配置
- Derby 工具
- ij 工具
- Derby 中的 SQL 查询
- 在 Derby 中使用 JDBC 进行编程
- Derby 安全
- 使用 Derby & Apache Tomcat
- NetBeans 和 Derby
- SQLAlchemy 教程
- SQLAlchemy 简介
- 原始 SQL
- 模式定义语言
- SQL 表达式语言
- SQLAlchemy 中的对象关系映射器
- MongoDB PHP 教程
- MongoDB JavaScript 教程
- MongoDB Ruby 教程
- Spring JdbcTemplate 教程
- JDBI 教程
- MyBatis 教程
- Hibernate Derby 教程
- ZetCode .NET 教程
- Visual Basic 教程
- Visual Basic
- Visual Basic 语法结构
- 基本概念
- Visual Basic 数据类型
- Visual Basic 中的字符串
- 运算符
- 控制流
- Visual Basic 数组
- Visual Basic 中的过程&函数
- 在 Visual Basic 中组织代码
- 面向对象编程
- Visual Basic 中的面向对象编程 II
- Visual Basic 中的集合
- 输入和输出
- C# 教程
- C# 语言
- C# 语法结构
- C# 基础
- C# 数据类型
- C# 中的字符串
- C# 运算符
- C# 中的流控制
- C# 数组
- C# 面向对象编程
- C# 中的方法
- C# 面向对象编程 II
- C# 属性
- C# 结构
- C# 委托
- 命名空间
- C# 集合
- C# 输入和输出
- C# 目录教程
- C# 字典教程
- 在 C# 中读取文本文件
- C# 中的日期和时间
- 在 C# 中读取网页
- C# HttpClient教程
- ASP.NET Core 教程
- ZetCode 图形教程
- Java 2D 游戏教程
- Java 游戏基础
- 动画
- 移动精灵
- 碰撞检测
- Java 益智游戏
- Java Snake
- Breakout 游戏
- Java 俄罗斯方块
- Java 吃豆人
- Java 太空侵略者
- Java 扫雷
- Java 推箱子
- Java 2D 教程
- 介绍
- 基本绘图
- 形状和填充
- 透明度
- 合成
- 剪裁
- 变换
- 特效
- 图像
- 文字和字体
- 命中测试,移动物体
- 俄罗斯方块
- Cario 图形教程
- Cario 图形库
- Cario 定义
- Cairo 后端
- Cairo 基本图形
- 形状和填充
- 渐变
- 透明度
- 合成
- 剪裁和遮罩
- 变换
- Cairo 文字
- Cairo 中的图像
- 根窗口
- PyCairo 教程
- PyCairo 简介
- PyCairo 后端
- PyCairo 中的基本绘图
- PyCairo 形状和填充
- PyCairo 渐变
- PyCairo 剪裁&遮罩
- PyCairo 的透明度
- PyCairo 中的变换
- PyCairo 中的文字
- PyCairo 中的图像
- 根窗口
- HTML5 画布教程
- 介绍
- HTML5 画布中的直线
- HTML5 画布形状
- HTML5 画布填充
- HTML5 画布中的透明度
- HTML5 画布合成
- HTML5 canvas 中的变换
- HTML5 画布中的文字
- HTML5 画布中的动画
- HTML5 画布中的 Snake
- ZetCode GUI 教程
- Windows API 教程
- Windows API 简介
- Windows API main函数
- Windows API 中的系统函数
- Windows API 中的字符串
- Windows API 中的日期和时间
- Windows API 中的一个窗口
- UI 的第一步
- Windows API 菜单
- Windows API 对话框
- Windows API 控件 I
- Windows API 控件 II
- Windows API 控件 III
- Windows API 中的高级控件
- Windows API 中的自定义控件
- Windows API 中的 GDI
- PyQt4 教程
- PyQt4 简介
- PyQt4 中的第一个程序
- PyQt4 中的菜单和工具栏
- PyQt4 中的布局管理
- PyQt4 中的事件和信号
- PyQt4 中的对话框
- PyQt4 小部件
- PyQt4 小部件 II
- PyQt4 中的拖放
- PyQt4 中的绘图
- PyQt4 中的自定义小部件
- PyQt4 中的俄罗斯方块游戏
- PyQt5 教程
- PyQt5 简介
- PyQt5 日期和时间
- PyQt5 中的第一个程序
- PyQt5 中的菜单和工具栏
- PyQt5 中的布局管理
- PyQt5 中的事件和信号
- PyQt5 中的对话框
- PyQt5 小部件
- PyQt5 小部件 II
- PyQt5 拖放
- PyQt5 中的绘图
- PyQt5 中的自定义小部件
- PyQt5 中的俄罗斯方块
- Qt4 教程
- Qt4 工具包简介
- Qt4 工具类
- Qt4 中的字符串
- Qt4 中的日期和时间
- 在 Qt4 中使用文件和目录
- Qt4 中的第一个程序
- Qt4 中的菜单和工具栏
- Qt4 中的布局管理
- Qt4 中的事件和信号
- Qt4 小部件
- Qt4 小部件 II
- Qt4 中的绘图
- Qt4 中的自定义小部件
- Qt4 中的打砖块游戏
- Qt5 教程
- Qt5 工具包简介
- Qt5 中的字符串
- Qt5 中的日期和时间
- Qt5 中的容器
- 在 Qt5 中处理文件和目录
- Qt5 中的第一个程序
- Qt5 中的菜单和工具栏
- Qt5 中的布局管理
- Qt5 中的事件和信号
- Qt5 小部件
- Qt5 小部件 II
- Qt5 中的绘图
- Qt5 中的自定义小部件
- Qt5 中的贪食蛇
- Qt5 中的打砖块游戏
- PySide 教程
- PySide 工具包简介
- PySide 中的第一个程序
- PySide 中的菜单和工具栏
- PySide 中的布局管理
- PySide 中的事件和信号
- PySide 中的对话框
- PySide 小部件
- PySide 小部件 II
- 在 PySide 中拖放
- 在 PySide 中绘图
- PySide 中的自定义小部件
- PySide 中的俄罗斯方块游戏
- Tkinter 教程
- Tkinter 简介
- Tkinter 中的布局管理
- Tkinter 标准小部件属性
- Tkinter 小部件
- Tkinter 中的菜单和工具栏
- Tkinter 中的对话框
- Tkinter 中的绘图
- Tkinter 中的贪食蛇
- Tcl/Tk 教程
- Tcl/Tk 简介
- Tcl/Tk 中的布局管理
- Tcl/Tk 小部件
- Tcl/Tk 中的菜单和工具栏
- Tcl/Tk 中的对话框
- Tcl/Tk 绘图
- 贪食蛇
- Qt 快速教程
- Java Swing 教程
- Java Swing 简介
- Java Swing 首个程序
- Java Swing 中的菜单和工具栏
- Swing 布局管理
- GroupLayout管理器
- Java Swing 事件
- 基本的 Swing 组件
- 基本的 Swing 组件 II
- Java Swing 对话框
- Java Swing 模型架构
- Swing 中的拖放
- Swing 中的绘图
- Java Swing 中的可调整大小的组件
- Java Swing 中的益智游戏
- 俄罗斯方块
- JavaFX 教程
- JavaFX 简介
- JavaFX 首个程序
- JavaFX 布局窗格
- 基本的 JavaFX 控件
- 基本 JavaFX 控件 II
- JavaFX 事件
- JavaFX 效果
- JavaFX 动画
- JavaFX 画布
- JavaFX 图表
- Java SWT 教程
- Java SWT 简介
- Java SWT 中的布局管理
- Java SWT 中的菜单和工具栏
- Java SWT 中的小部件
- Table小部件
- Java SWT 中的对话框
- Java SWT 绘图
- Java SWT 中的贪食蛇
- wxWidgets 教程
- wxWidgets 简介
- wxWidgets 助手类
- wxWidgets 中的第一个程序
- wxWidgets 中的菜单和工具栏
- wxWidgets 中的布局管理
- wxWidgets 中的事件
- wxWidgets 中的对话框
- wxWidgets 小部件
- wxWidgets 小部件 II
- wxWidgets 中的拖放
- wxWidgets 中的设备上下文
- wxWidgets 中的自定义小部件
- wxWidgets 中的俄罗斯方块游戏
- wxPython 教程
- wxPython 简介
- 第一步
- 菜单和工具栏
- wxPython 中的布局管理
- wxPython 中的事件
- wxPython 对话框
- 小部件
- wxPython 中的高级小部件
- wxPython 中的拖放
- wxPython 图形
- 创建自定义小部件
- wxPython 中的应用框架
- wxPython 中的俄罗斯方块游戏
- C# Winforms Mono 教程
- Mono Winforms 简介
- Mono Winforms 中的第一步
- Mono Winforms 中的布局管理
- Mono Winforms 中的菜单和工具栏
- Mono Winforms 中的基本控件
- Mono Winforms 中的高级控件
- 对话框
- Mono Winforms 中的拖放
- Mono Winforms 中的绘图
- Mono Winforms 中的贪食蛇
- Java Gnome 教程
- Java Gnome 简介
- Java Gnome 的第一步
- Java Gnome 中的布局管理
- Java Gnome 中的布局管理 II
- Java Gnome 中的菜单
- Java Gnome 中的工具栏
- Java Gnome 中的事件
- Java Gnome 中的小部件
- Java Gnome 中的小部件 II
- Java Gnome 中的高级小部件
- Java Gnome 中的对话框
- Java Gnome 中的 Pango
- 在 Java Gnome 中用 Cairo 绘图
- Cario 绘图 II
- Java Gnome 中的贪食蛇
- QtJambi 教程
- QtJambi 简介
- QtJambi 中的布局管理
- QtJambi 中的小部件
- QtJambi 中的菜单和工具栏
- QtJambi 对话框
- QtJambi 中的绘图
- QtJambi 中的自定义小部件
- 贪食蛇
- GTK+ 教程
- GTK+ 简介
- GTK+ 中的第一个程序
- GTK+ 中的菜单和工具栏
- GTK+ 布局管理
- GTK+ 事件和信号
- GTK+ 对话框
- GTK+ 小部件
- GTK+ 小部件 II
- GtkTreeView小部件
- GtkTextView小部件
- 自定义 GTK+ 小部件
- Ruby GTK 教程
- Ruby GTK 简介
- Ruby GTK 中的布局管理
- Ruby GTK 中的小部件
- Ruby GTK 中的菜单和工具栏
- Ruby GTK 中的对话框
- Ruby GTK Cario 绘图
- Ruby GTK 中的自定义小部件
- Ruby GTK 中的贪食蛇
- GTK# 教程
- GTK# 简介
- GTK 的第一步
- GTK# 中的布局管理
- GTK 中的菜单
- GTK# 中的工具栏
- GTK# 中的事件
- GTK# 中的小部件
- GTK 中的小部件 II
- GTK# 中的高级小部件
- GTK# 中的对话框
- Pango
- GTK# 中的 Cario 绘图
- GTK# 中的 Cario 绘图 II
- GTK# 中的自定义小部件
- Visual Basic GTK# 教程
- Visual Basic GTK# 简介
- 布局管理
- 小部件
- 菜单和工具栏
- 对话框
- Cario 绘图
- 自定义小部件
- 贪食蛇
- PyGTK 教程
- PyGTK 简介
- PyGTK 的第一步
- PyGTK 中的布局管理
- PyGTK 中的菜单
- PyGTK 中的工具栏
- PyGTK 中的事件和信号
- PyGTK 中的小部件
- PyGTK 中的小部件 II
- PyGTK 中的高级小部件
- PyGTK 中的对话框
- Pango
- Pango II
- PyGTK 中的 Cario 绘图
- Cario 绘图 II
- PyGTK 中的贪食蛇游戏
- PyGTK 中的自定义小部件
- PHP GTK 教程
- PHP GTK 简介
- PHP GTK 中的布局管理
- PHP GTK 中的小部件
- PHP GTK 中的菜单和工具栏
- 对话框
- Cario 绘图
- 自定义小部件
- 贪食蛇
- C# Qyoto 教程
- Qyoto 介绍
- 布局管理
- Qyoto 中的小部件
- Qyoto 中的菜单和工具栏
- Qyoto 对话框
- Qyoto 中的绘图
- Qyoto 中的绘图 II
- Qyoto 中的自定义小部件
- 贪食蛇
- Ruby Qt 教程
- Ruby Qt 简介
- Ruby Qt 中的布局管理
- Ruby Qt 中的小部件
- 菜单和工具栏
- Ruby Qt 中的对话框
- 用 Ruby Qt 绘图
- Ruby Qt 中的自定义小部件
- Ruby Qt 中的贪食蛇
- Visual Basic Qyoto 教程
- Qyoto 介绍
- 布局管理
- Qyoto 中的小部件
- Qyoto 中的菜单和工具栏
- Qyoto 对话框
- Qyoto 中的绘图
- Qyoto 中的自定义小部件
- 贪食蛇
- Mono IronPython Winforms 教程
- 介绍
- IronPython Mono Winforms 中的第一步
- 布局管理
- 菜单和工具栏
- Mono Winforms 中的基本控件
- Mono Winforms 中的基本控件 II
- Mono Winforms 中的高级控件
- 对话框
- Mono Winforms 中的拖放
- 绘图
- IronPython Mono Winforms 中的绘图 II
- IronPython Mono Winforms 中的贪食蛇
- IronPython Mono Winforms 中的俄罗斯方块游戏
- FreeBASIC GTK 教程
- Jython Swing 教程
- Jython Swing 简介
- Jython Swing 中的布局管理
- Jython Swing 中的组件
- Jython Swing 中的菜单和工具栏
- Jython Swing 中的对话框
- Jython Swing 中的绘图
- Jython Swing 中的半字节
- JRuby Swing 教程
- JRuby Swing 简介
- JRuby Swing 中的布局管理
- JRuby Swing 中的组件
- 菜单和工具栏
- JRuby Swing 中的对话框
- 在 JRuby Swing 中绘图
- JRuby Swing 中的贪食蛇
- Visual Basic Winforms 教程
- Visual Basic Winforms 简介
- 布局管理
- 基本控制
- 进阶控件
- 菜单和工具栏
- 对话框
- 绘图
- 拖放
- 贪食蛇
- JavaScript GTK 教程
- JavaScript GTK 简介
- 布局管理
- JavaScript GTK 中的小部件
- JavaScript GTK 中的菜单和工具栏
- JavaScript GTK 中的对话框
- JavaScript GTK 中的 Cario 绘图
- ZetCode Java 教程
- Java 教程
- Java 语言
- Java 语法结构
- Java 基础
- Java 数据类型
- Java 数据类型 II
- Java 字符串
- Java 数组
- Java 表达式
- Java 控制流程
- Java 面向对象的编程
- Java 方法
- Java 面向对象编程 II
- Java 包
- Java 中的异常
- Java 集合
- Java 流
- Java Future 教程
- Java Comparable和Comparator
- Java DOM 教程
- Java MVC 教程
- Java SAX 教程
- Java JAXB 教程
- Java JSON 处理教程
- Java H2 教程
- MongoDB Java 教程
- Java 正则表达式教程
- Java PDFBox 教程
- Java 文件教程
- Java Files.list教程
- Java Files.walk教程
- Java DirectoryStream教程
- Java 外部与内部迭代器
- Java 文件大小
- 用 Java 创建目录
- 用 Java 创建文件
- Java Log4j 教程
- Gson 教程
- Java RequestDispatcher
- Java HTTP GET/POST 请求
- Java InputStream教程
- Java FileOutputStream教程
- Java FileInputStream教程
- Java ZipInputStream教程
- Java FileWriter教程
- EJB 简介
- Java forEach教程
- Jetty 教程
- Tomcat Derby 教程
- Stripes 介绍
- 使用 Stripes 的 Java webapp,MyBatis,& Derby
- EclipseLink 简介
- Java 中的数据源
- JSTL 中的 SQL 查询标记
- Java 验证过滤器
- Hibernate 验证器
- 用 Java 显示图像
- Play 框架简介
- Spark Java 简介
- Java ResourceBundle教程
- Jtwig 教程
- Java Servlet 教程
- Java 套接字教程
- FreeMarker 教程
- Android 教程
- Java EE 5 教程
- JSoup 教程
- JFreeChart 教程
- ImageIcon教程
- 用 Java 复制文件
- Java 文件时间教程
- 如何使用 Java 获取当前日期时间
- Java 列出目录内容
- Java 附加到文件
- Java ArrayList教程
- 用 Java 读写 ICO 图像
- Java int到String的转换
- Java HashSet教程
- Java HashMap教程
- Java static关键字
- Java 中的HashMap迭代
- 用 Java 过滤列表
- 在 Java 中读取网页
- Java 控制台应用
- Java 集合的便利工厂方法
- Google Guava 简介
- OpenCSV 教程
- 用 Java8 的StringJoiner连接字符串
- Java 中元素迭代的历史
- Java 谓词
- Java StringBuilder
- Java 分割字串教学
- Java NumberFormat
- Java TemporalAdjusters教程
- Apache FileUtils教程
- Java Stream 过滤器
- Java 流归约
- Java 流映射
- Java InputStreamReader教程
- 在 Java 中读取文本文件
- Java Unix 时间
- Java LocalTime
- Java 斐波那契
- Java ProcessBuilder教程
- Java 11 的新功能
- ZetCode JavaScript 教程
- Ramda 教程
- Lodash 教程
- Collect.js 教程
- Node.js 简介
- Node HTTP 教程
- Node-config 教程
- Dotenv 教程
- Joi 教程
- Liquid.js 教程
- faker.js 教程
- Handsontable 教程
- PouchDB 教程
- Cheerio 教程
- Axios 教程
- Jest 教程
- JavaScript 正则表达式
- 用 JavaScript 创建对象
- Big.js 教程
- Moment.js 教程
- Day.js 教程
- JavaScript Mustache 教程
- Knex.js 教程
- MongoDB JavaScript 教程
- Sequelize 教程
- Bookshelf.js 教程
- Node Postgres 教程
- Node Sass 教程
- Document.querySelector教程
- Document.all教程
- JSON 服务器教程
- JavaScript 贪食蛇教程
- JavaScript 构建器模式教程
- JavaScript 数组
- XMLHttpRequest教程
- 从 JavaScript 中的 URL 读取 JSON
- 在 JavaScript 中循环遍历 JSON 数组
- jQuery 教程
- Google 图表教程
- ZetCode Kotlin 教程
- Kotlin Hello World 教程
- Kotlin 变量
- Kotlin 的运算符
- Kotlin when表达式
- Kotlin 数组
- Kotlin 范围
- Kotlin Snake
- Kotlin Swing 教程
- Kotlin 字符串
- Kotlin 列表
- Kotlin 映射
- Kotlin 集合
- Kotlin 控制流程
- Kotlin 写入文件
- Kotlin 读取文件教程
- Kotlin 正则表达式
- ZetCode 其它教程
- TCL 教程
- Tcl
- Tcl 语法结构
- Tcl 中的基本命令
- Tcl 中的表达式
- Tcl 中的控制流
- Tcl 中的字符串
- Tcl 列表
- Tcl 中的数组
- Tcl 中的过程
- 输入&输出
- AWK 教程
- Vaadin 教程
- Vaadin 框架介绍
- Vaadin Grid教程
- Vaadin TextArea教程
- Vaadin ComboBox教程
- Vaadin Slider教程
- Vaadin CheckBox教程
- Vaadin Button教程
- Vaadin DateField教程
- Vaadin Link教程
- ZetCode PHP 教程
- PHP 教程
- PHP
- PHP 语法结构
- PHP 基础
- PHP 数据类型
- PHP 字符串
- PHP 运算符
- PHP 中的控制流
- PHP 数组
- PHP 数组函数
- PHP 中的函数
- PHP 正则表达式
- PHP 中的面向对象编程
- PHP 中的面向对象编程 II
- PHP Carbon 教程
- PHP Monolog 教程
- PHP 配置教程
- PHP Faker 教程
- Twig 教程
- Valitron 教程
- Doctrine DBAL QueryBuilder 教程
- PHP Respect 验证教程
- PHP Rakit 验证教程
- PHP PDO 教程
- CakePHP 数据库教程
- PHP SQLite3 教程
- PHP 文件系统函数
- ZetCode Python 教程
- Python 教程
- Python 语言
- 交互式 Python
- Python 语法结构
- Python 数据类型
- Python 字符串
- Python 列表
- Python 字典
- Python 运算符
- Python 关键字
- Python 函数
- Python 中的文件
- Python 中的面向对象编程
- Python 模块
- Python 中的包
- Python 异常
- Python 迭代器和生成器
- Python 内省
- Python Faker 教程
- Python f 字符串教程
- Python bcrypt 教程
- Python 套接字教程
- Python smtplib教程
- OpenPyXL 教程
- Python pathlib教程
- Python YAML 教程
- Python 哈希教程
- Python ConfigParser教程
- Python 日志教程
- Python argparse 教程
- Python SQLite 教程
- Python Cerberus 教程
- Python PostgreSQL 教程
- PyMongo 教程
- PyMySQL 教程
- Peewee 教程
- pyDAL 教程
- pytest 教程
- Bottle 教程
- Python Jinja 教程
- PrettyTable 教程
- BeautifulSoup 教程
- pyquery 教程
- Python for循环
- Python 反转
- Python Lambda 函数
- Python 集合
- Python 映射
- Python CSV 教程-读写 CSV
- Python 正则表达式
- Python SimpleJson 教程
- SymPy 教程
- Pandas 教程
- Matplotlib 教程
- Pillow 教程
- Python FTP 教程
- Python Requests 教程
- Python Arrow 教程
- Python 列表推导式
- Python 魔术方法
- PyQt 中的QPropertyAnimation
- PyQt 中的QNetworkAccessManager
- ZetCode Ruby 教程
- Ruby 教程
- Ruby
- Ruby 语法结构
- Ruby 基础
- Ruby 变量
- Ruby 中的对象
- Ruby 数据类型
- Ruby 字符串
- Ruby 表达式
- Ruby 控制流
- Ruby 数组
- Ruby 哈希
- Ruby 中的面向对象编程
- Ruby 中的面向对象编程 II
- Ruby 正则表达式
- Ruby 输入&输出
- Ruby HTTPClient教程
- Ruby Faraday 教程
- Ruby Net::HTTP教程
- ZetCode Servlet 教程
- 从 Java Servlet 提供纯文本
- Java Servlet JSON 教程
- Java Servlet HTTP 标头
- Java Servlet 复选框教程
- Java servlet 发送图像教程
- Java Servlet JQuery 列表教程
- Servlet FreeMarker JdbcTemplate 教程-CRUD 操作
- jQuery 自动补全教程
- Java servlet PDF 教程
- servlet 从 WAR 内读取 CSV 文件
- Java HttpServletMapping
- EasyUI datagrid
- Java Servlet RESTFul 客户端
- Java Servlet Log4j 教程
- Java Servlet 图表教程
- Java ServletConfig教程
- Java Servlet 读取网页
- 嵌入式 Tomcat
- Java Servlet 分页
- Java Servlet Weld 教程
- Java Servlet 上传文件
- Java Servlet 提供 XML
- Java Servlet 教程
- JSTL forEach标签
- 使用 jsGrid 组件
- ZetCode Spring 教程
- Spring @Bean注解教程
- Spring @Autowired教程
- Spring @GetMapping教程
- Spring @PostMapping教程
- Spring @DeleteMapping教程
- Spring @RequestMapping教程
- Spring @PathVariable教程
- Spring @RequestBody教程
- Spring @RequestHeader教程
- Spring Cookies 教程
- Spring 资源教程
- Spring 重定向教程
- Spring 转发教程
- Spring ModelAndView教程
- Spring MessageSource教程
- Spring AnnotationConfigApplicationContext
- Spring BeanFactoryPostProcessor教程
- Spring BeanFactory教程
- Spring context:property-placeholder教程
- Spring @PropertySource注解教程
- Spring @ComponentScan教程
- Spring @Configuration教程
- Spring C 命名空间教程
- Spring P 命名空间教程
- Spring bean 引用教程
- Spring @Qualifier注解教程
- Spring ClassPathResource教程
- Spring 原型作用域 bean
- Spring Inject List XML 教程
- Spring 概要文件 XML 教程
- Spring BeanDefinitionBuilder教程
- Spring 单例作用域 bean
- 独立的 Spring 应用
- 经典 Spring 应用中的JdbcTemplate
- Spring EmbeddedDatabaseBuilder教程
- Spring HikariCP 教程
- Spring Web 应用简介
- Spring BeanPropertyRowMapper教程
- Spring DefaultServlet教程
- Spring WebSocket 教程
- Spring WebJars 教程
- Spring @MatrixVariable教程
- Spring Jetty 教程
- Spring 自定义 404 错误页面教程
- Spring WebApplicationInitializer教程
- Spring BindingResult教程
- Spring FreeMarker 教程
- Spring Thymeleaf 教程
- Spring ResourceHandlerRegistry教程
- SpringRunner 教程
- Spring MockMvc 教程
- ZetCode Spring Boot 教程
- Spring Boot 发送电子邮件教程
- Spring Boot WebFlux 教程
- Spring Boot ViewControllerRegistry教程
- Spring Boot CommandLineRunner教程
- Spring Boot ApplicationReadyEvent 教程
- Spring Boot CORS 教程
- Spring Boot @Order教程
- Spring Boot @Lazy教程
- Spring Boot Flash 属性
- Spring Boot CrudRepository 教程
- Spring Boot JpaRepository 教程
- Spring Boot findById 教程
- Spring Boot Data JPA @NamedQuery教程
- Spring Boot Data JPA @Query教程
- Spring Boot Querydsl 教程
- Spring Boot Data JPA 排序教程
- Spring Boot @DataJpaTest教程
- Spring Boot TestEntityManager 教程
- Spring Boot Data JPA 派生的查询
- Spring Boot Data JPA 查询示例
- Spring Boot Jersey 教程
- Spring Boot CSV 教程
- SpringBootServletInitializer教程
- 在 Spring Boot 中加载资源
- Spring Boot H2 REST 教程
- Spring Boot RestTemplate
- Spring Boot REST XML 教程
- Spring Boot Moustache 教程
- Spring Boot Thymeleaf 配置
- Spring Boot 自动控制器
- Spring Boot FreeMarker 教程
- Spring Boot Environment
- Spring Boot Swing 集成教程
- 在 Spring Boot 中提供图像文件
- 在 Spring Boot 中创建 PDF 报告
- Spring Boot 基本注解
- Spring Boot @ResponseBody教程
- Spring Boot @PathVariable教程
- Spring Boot REST Data JPA 教程
- Spring Boot @RequestParam教程
- Spring Boot 列出 bean
- Spring Boot @Bean
- Spring Boot @Qualifier教程
- 在 Spring Boot 中提供静态内容
- Spring Boot Whitelabel 错误
- Spring Boot DataSourceBuilder 教程
- Spring Boot H2 教程
- Spring Boot Web JasperReports 集成
- Spring Boot iText 教程
- Spring Boot cmd JasperReports 集成
- Spring Boot RESTFul 应用
- Spring Boot 第一个 Web 应用
- Spring Boot Groovy CLI
- Spring Boot 上传文件
- Spring Boot @ExceptionHandler
- Spring Boot @ResponseStatus
- Spring Boot ResponseEntity
- Spring Boot @Controller
- Spring Boot @RestController
- Spring Boot @PostConstruct
- Spring Boot @Component
- Spring Boot @ConfigurationProperties教程
- Spring Boot @Repository
- Spring Boot MongoDB 教程
- Spring Boot MongoDB Reactor 教程
- Spring Boot PostgreSQL 教程
- Spring Boot @ModelAttribute
- Spring Boot 提交表单教程
- Spring Boot Model
- Spring Boot MySQL 教程
- Spring Boot GenericApplicationContext
- SpringApplicationBuilder教程
- Spring Boot Undertow 教程
- Spring Boot 登录页面教程
- Spring Boot RouterFunction 教程
- ZetCode Symfony 教程
- Symfony DBAL 教程
- Symfony 表单教程
- Symfony CSRF 教程
- Symfony Vue 教程
- Symfony 简介
- Symfony 请求教程
- Symfony HttpClient教程
- Symfony Flash 消息
- 在 Symfony 中发送邮件
- Symfony 保留表单值
- Symfony @Route注解教程
- Symfony 创建路由
- Symfony 控制台命令教程
- Symfony 上传文件
- Symfony 服务教程
- Symfony 验证教程
- Symfony 翻译教程