在 wx 中将图像添加到 ListCtrl 的最右边的列 Python
Add images to rightmost column of ListCtrl in wx Python
TLDR
是否可以将图像添加到 Python 中的 wx.ListCtrl 的 second/rightmost 列?这就是我要找的:
背景
我有一个wx.ListCtrl和图像列表如下:
self.health_grid = wx.ListCtrl(self, style=wx.LC_REPORT| wx.LC_ALIGN_TOP)
self.health_grid.InsertColumn(0, heading="Organ")
self.health_grid.InsertColumn(1, heading="Status")
self.health_icons = wx.ImageList(16, 16, False, 0)
self.unhealthy = wx.Bitmap(self.getFilePath("gui" + os.sep + "images" + os.sep + "unhealthy.png"))
self.health_icons.Add(self.unhealthy)
self.healthy = wx.Bitmap(self.getFilePath("gui" + os.sep + "images" + os.sep + "healthy.png"))
self.health_icons.Add(self.healthy)
self.unknown = wx.Bitmap(self.getFilePath("gui" + os.sep + "images" + os.sep + "unknown.png"))
self.health_icons.Add(self.unknown)
self.health_grid.SetImageList(self.health_icons, wx.IMAGE_LIST_SMALL)
尝试 1
当我按以下方式添加我的项目时:
self.health_grid.InsertImageStringItem(self.health_grid.GetItemCount(), "Heart", 0)
self.health_grid.InsertImageStringItem(self.health_grid.GetItemCount(), "Brain", 0)
self.health_grid.InsertImageStringItem(self.health_grid.GetItemCount(), "Lungs", 1)
self.health_grid.InsertImageStringItem(self.health_grid.GetItemCount(), "Liver", 2)
它产生以下输出:
这是意料之中的;没有地方可以明确说明我希望将我的图像放入第 1 列。
尝试 2
当我尝试使用附加方法添加并将位图设置为第二列项目时,如下所示:
self.health_grid.Append(["Heart", self.unhealthy])
它产生这个输出:
这个稍微好一点;至少引用已添加到第二列,但它仍然不是我想要的。
尝试 2.5
我做了修改,试图使位图显示:
self.static_unhealthy = wx.StaticBitmap(self, -1, self.unhealthy)
self.sizer = wx.BoxSizer(wx.HORIZONTAL)
self.sizer.Add(self.static_unhealthy, 0)
self.health_grid.Append(["Heart", self.sizer])
它产生这个:
另一个错误的版本。
尝试 3
我试图在以下代码中明确地将图像分配给第二列,将文本分配给第一列:
item = wx.ListItem()
item.SetId(wx.NewId())
item.SetColumn(0)
item.SetText("Heart")
item.SetColumn(1)
item.SetImage(0)
self.health_grid.InsertItem(item)
然而,这产生了这个:
我想这是最接近我想要的,但仍然失败了。
终于
有没有可能生产出我想要的东西?我错过了一些明显的东西吗?
据我所知,在 Windows 下无法实现我正在寻找的功能,因此我采用了如下不同的方法。
使用 wx.grid.Grid 而不是 wx.ListCtrl 并实现了 wx.grid.PyGridCellRenderer 的覆盖版本,如下面的代码摘录所示:
import wx.grid as grid
import os
import wx
class healthStatus(wx.Frame):
organs = ["heart", "lungs", "brain", "liver"]
health_icons = []
(row, progress) = (0, 0)
def __init__(self, parent, id, title):
# initialise the frame container
wx.Frame.__init__(self, parent, id, title)
# main gui sizer, shall be the sizer for the window
self.main_sizer = wx.BoxSizer(wx.VERTICAL)
self.health_grid = grid.Grid(self)
self.health_grid.CreateGrid(len(self.organs),2)
self.health_grid.SetColLabelValue(0, "Organ")
self.health_grid.SetColLabelValue(1, "Status")
self.health_grid.SetRowLabelSize(0)
try:
self.health_icons.append(self.getFilePath("images" + os.sep + "unknown.png"))
self.health_icons.append(self.getFilePath("images" + os.sep + "unhealthy.png"))
self.health_icons.append(self.getFilePath("images" + os.sep + "healthy.png"))
except Exception as e:
wx.MessageBox("Cannot load icons. \n Please ensure the images directory has not been moved\n\n"
+ e.message, "Cannot Load Icons", wx.ICON_ERROR)
index = 0
for organ in self.organs:
self.addItem(index, organ)
index += 1
self.main_sizer.Add(self.health_grid, 0, wx.ALL, 5)
self.testing_button = wx.Button(self, wx.ID_ANY, "Testing")
self.testing_button.Bind(wx.EVT_BUTTON, self.onProgress)
self.main_sizer.Add(self.testing_button, 0, wx.ALL, 5)
self.SetSizer(self.main_sizer)
self.Fit()
def addItem(self, index, organ):
self.health_grid.SetCellValue(index, 0, organ)
self.health_grid.SetCellRenderer(index, 1, BitmapRenderer(self.health_icons[0]))
def updateProgress(self, index, progress):
self.health_grid.SetCellRenderer(index, 1, BitmapRenderer(self.health_icons[progress]))
self.health_grid.Refresh()
def getFilePath(self, directory):
curr = os.getcwd() + os.sep
parent = "listctrlproblem" + os.sep
parent_offset = len(parent)
if curr.index(parent) + parent_offset != len(curr + os.sep):
curr = curr[:curr.index(parent) + parent_offset]
print curr
return curr + os.sep + directory
def onProgress(self, evt):
if self.health_grid.GetNumberRows() > 1:
if self.progress + 1 < len(self.health_icons):
self.progress += 1
elif self.row < self.health_grid.GetNumberRows() + 1:
self.progress = 0
self.row +=1
self.updateProgress(self.row, self.progress)
class BitmapRenderer(wx.grid.PyGridCellRenderer):
def __init__(self, image):
self.image = image
wx.grid.PyGridCellRenderer.__init__(self)
def Draw(self, grid, attr, dc, rect, row, col, is_selected):
bmp = wx.Bitmap(self.image)
dc.DrawBitmap(bmp, rect.X, rect.Y)
def Clone(self):
return self.__class__()
app = wx.App(False)
frame = healthStatus(None, -1, "Organ Status")
frame.Show(1)
app.MainLoop()
这会在 Linux 上创建以下输出:
并且 Windows 上的以下输出:
TLDR
是否可以将图像添加到 Python 中的 wx.ListCtrl 的 second/rightmost 列?这就是我要找的:
背景
我有一个wx.ListCtrl和图像列表如下:
self.health_grid = wx.ListCtrl(self, style=wx.LC_REPORT| wx.LC_ALIGN_TOP)
self.health_grid.InsertColumn(0, heading="Organ")
self.health_grid.InsertColumn(1, heading="Status")
self.health_icons = wx.ImageList(16, 16, False, 0)
self.unhealthy = wx.Bitmap(self.getFilePath("gui" + os.sep + "images" + os.sep + "unhealthy.png"))
self.health_icons.Add(self.unhealthy)
self.healthy = wx.Bitmap(self.getFilePath("gui" + os.sep + "images" + os.sep + "healthy.png"))
self.health_icons.Add(self.healthy)
self.unknown = wx.Bitmap(self.getFilePath("gui" + os.sep + "images" + os.sep + "unknown.png"))
self.health_icons.Add(self.unknown)
self.health_grid.SetImageList(self.health_icons, wx.IMAGE_LIST_SMALL)
尝试 1
当我按以下方式添加我的项目时:
self.health_grid.InsertImageStringItem(self.health_grid.GetItemCount(), "Heart", 0)
self.health_grid.InsertImageStringItem(self.health_grid.GetItemCount(), "Brain", 0)
self.health_grid.InsertImageStringItem(self.health_grid.GetItemCount(), "Lungs", 1)
self.health_grid.InsertImageStringItem(self.health_grid.GetItemCount(), "Liver", 2)
它产生以下输出:
这是意料之中的;没有地方可以明确说明我希望将我的图像放入第 1 列。
尝试 2
当我尝试使用附加方法添加并将位图设置为第二列项目时,如下所示:
self.health_grid.Append(["Heart", self.unhealthy])
它产生这个输出:
这个稍微好一点;至少引用已添加到第二列,但它仍然不是我想要的。
尝试 2.5
我做了修改,试图使位图显示:
self.static_unhealthy = wx.StaticBitmap(self, -1, self.unhealthy)
self.sizer = wx.BoxSizer(wx.HORIZONTAL)
self.sizer.Add(self.static_unhealthy, 0)
self.health_grid.Append(["Heart", self.sizer])
它产生这个:
另一个错误的版本。
尝试 3
我试图在以下代码中明确地将图像分配给第二列,将文本分配给第一列:
item = wx.ListItem()
item.SetId(wx.NewId())
item.SetColumn(0)
item.SetText("Heart")
item.SetColumn(1)
item.SetImage(0)
self.health_grid.InsertItem(item)
然而,这产生了这个:
我想这是最接近我想要的,但仍然失败了。
终于
有没有可能生产出我想要的东西?我错过了一些明显的东西吗?
据我所知,在 Windows 下无法实现我正在寻找的功能,因此我采用了如下不同的方法。
使用 wx.grid.Grid 而不是 wx.ListCtrl 并实现了 wx.grid.PyGridCellRenderer 的覆盖版本,如下面的代码摘录所示:
import wx.grid as grid
import os
import wx
class healthStatus(wx.Frame):
organs = ["heart", "lungs", "brain", "liver"]
health_icons = []
(row, progress) = (0, 0)
def __init__(self, parent, id, title):
# initialise the frame container
wx.Frame.__init__(self, parent, id, title)
# main gui sizer, shall be the sizer for the window
self.main_sizer = wx.BoxSizer(wx.VERTICAL)
self.health_grid = grid.Grid(self)
self.health_grid.CreateGrid(len(self.organs),2)
self.health_grid.SetColLabelValue(0, "Organ")
self.health_grid.SetColLabelValue(1, "Status")
self.health_grid.SetRowLabelSize(0)
try:
self.health_icons.append(self.getFilePath("images" + os.sep + "unknown.png"))
self.health_icons.append(self.getFilePath("images" + os.sep + "unhealthy.png"))
self.health_icons.append(self.getFilePath("images" + os.sep + "healthy.png"))
except Exception as e:
wx.MessageBox("Cannot load icons. \n Please ensure the images directory has not been moved\n\n"
+ e.message, "Cannot Load Icons", wx.ICON_ERROR)
index = 0
for organ in self.organs:
self.addItem(index, organ)
index += 1
self.main_sizer.Add(self.health_grid, 0, wx.ALL, 5)
self.testing_button = wx.Button(self, wx.ID_ANY, "Testing")
self.testing_button.Bind(wx.EVT_BUTTON, self.onProgress)
self.main_sizer.Add(self.testing_button, 0, wx.ALL, 5)
self.SetSizer(self.main_sizer)
self.Fit()
def addItem(self, index, organ):
self.health_grid.SetCellValue(index, 0, organ)
self.health_grid.SetCellRenderer(index, 1, BitmapRenderer(self.health_icons[0]))
def updateProgress(self, index, progress):
self.health_grid.SetCellRenderer(index, 1, BitmapRenderer(self.health_icons[progress]))
self.health_grid.Refresh()
def getFilePath(self, directory):
curr = os.getcwd() + os.sep
parent = "listctrlproblem" + os.sep
parent_offset = len(parent)
if curr.index(parent) + parent_offset != len(curr + os.sep):
curr = curr[:curr.index(parent) + parent_offset]
print curr
return curr + os.sep + directory
def onProgress(self, evt):
if self.health_grid.GetNumberRows() > 1:
if self.progress + 1 < len(self.health_icons):
self.progress += 1
elif self.row < self.health_grid.GetNumberRows() + 1:
self.progress = 0
self.row +=1
self.updateProgress(self.row, self.progress)
class BitmapRenderer(wx.grid.PyGridCellRenderer):
def __init__(self, image):
self.image = image
wx.grid.PyGridCellRenderer.__init__(self)
def Draw(self, grid, attr, dc, rect, row, col, is_selected):
bmp = wx.Bitmap(self.image)
dc.DrawBitmap(bmp, rect.X, rect.Y)
def Clone(self):
return self.__class__()
app = wx.App(False)
frame = healthStatus(None, -1, "Organ Status")
frame.Show(1)
app.MainLoop()
这会在 Linux 上创建以下输出:
并且 Windows 上的以下输出: