一直遇到一個問題,本來不想面對的。孰不知,終究還是要還...
之前利用了listmix的CheckListCtrlMixin在list table上增加checkbox。
不過一直遇到一個奇怪的現象,就是當我新增了一個image list後
image list的圖案會覆蓋在checkbox的位置上,導致我的checkbox被吃掉了 =口=
image list的圖案會覆蓋在checkbox的位置上,導致我的checkbox被吃掉了 =口=
Google了好久,一直無法找到方法。
一直不斷的改code亂試後,猜測原因應該是CheckListCtrlMixin有使用到image list
而我在新增image list後會把原本內建的覆蓋掉,導致checkbox的圖案變成我新增的圖案。
原本想將新增的圖案放入內建的image list中,但發現沒有append之類的method可用。
無計可施之下,只好繼續Google
皇天不負苦心人,查到了一個網頁: wxPython.lib.mixins.listctrl
其中,以下這段資料,證實了我的想法是正確的。
DESCRIPTION:
This script provide a mixin for ListCtrl which add a checkbox in the first
column of each row. It is inspired by limodou's CheckList.py(which can be
got from his NewEdit) and improved:
- You can just use InsertStringItem() to insert new items;
- Once a checkbox is checked/unchecked, the corresponding item is not
selected;
- You can use SetItemData() and GetItemData();
- Interfaces are changed to OnCheckItem(), IsChecked(), CheckItem().
You should not set a imagelist for the ListCtrl once this mixin is used.
這下該怎麼辦呢?
索性就如法炮製,建置一個新的image list,放入了checkbox以及自己所要增加的圖案。
索性就如法炮製,建置一個新的image list,放入了checkbox以及自己所要增加的圖案。
程式說明:listctrl會顯示所有的資料,預設是將所有的checkbox打勾。
當按下Execution button後,會依序對每個item顯示打勾的圖案。
下方就是這個sample的source code。
當然,由於我沒有附上圖片檔,所以記得要自己加上一個圖片檔喔!
當按下Execution button後,會依序對每個item顯示打勾的圖案。
下方就是這個sample的source code。
當然,由於我沒有附上圖片檔,所以記得要自己加上一個圖片檔喔!
import wx
import wx.lib.mixins.listctrl as listmix
import sys
import time
import locale
import re
import threading
from wx import ImageFromStream, BitmapFromImage
import cStringIO, zlib
# loaded the row data of checked image and unchecked image
def getUncheckData():
return zlib.decompress("Please copy it.")
def getUncheckBitmap():
return BitmapFromImage(getUncheckImage())
def getUncheckImage():
stream = cStringIO.StringIO(getUncheckData())
return ImageFromStream(stream)
def getCheckData():
return zlib.decompress("Please copy it.")
def getCheckBitmap():
return BitmapFromImage(getCheckImage())
def getCheckImage():
stream = cStringIO.StringIO(getCheckData())
return ImageFromStream(stream)
# list data
musicdata = {
1 : ("Jerry", "Man"),
2 : ("Annie", "Woman"),
3 : ("Nick", "Man"),
4 : ("Cosmo", "Man"),
5 : ("Always", "Man"),
6 : ("Jason", "Man"),
7 : ("James", "Man"),
8 : ("Andrew", "Man"),
9 : ("Ashley", "Woman"),
10: ("Stephanie", "Woman"),
11: ("Claire", "Woman"),
12: ("Fran", "Man")
}
# a thread to check the item sequentially
class ExecutionThread(threading.Thread):
def __init__(self, parent):
threading.Thread.__init__(self)
self.parent = parent
# --------------------------------------------------
# run thread
# --------------------------------------------------
def run(self):
for itemIdx in range(self.parent.list.GetItemCount()):
time.sleep(1)
self.parent.list.SetItemColumnImage(itemIdx, 3, self.parent.list.orange_image)
# added the listmix.CheckListCtrlMixin to add checkbox on eveny row
class TestVirtualList(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, listmix.CheckListCtrlMixin):
def __init__(self, parent, check_image=None, uncheck_image=None):
wx.ListCtrl.__init__( self, parent, -1, style=wx.LC_REPORT | wx.BORDER_SUNKEN | wx.LC_VRULES | wx.LC_HRULES)
listmix.CheckListCtrlMixin.__init__(self)
listmix.ListCtrlAutoWidthMixin.__init__(self)
# overwrote the image list
self.__imagelist_ = wx.ImageList(16, 16)
if not check_image:
check_image = BitmapFromImage(getCheckImage())
if not uncheck_image:
uncheck_image = BitmapFromImage(getUncheckImage())
self.uncheck_image = self.__imagelist_.Add(uncheck_image)
self.check_image = self.__imagelist_.Add(check_image)
orangeBmp = wx.Bitmap('checkOrange_16.png')
self.orange_image = self.__imagelist_.Add(orangeBmp)
self.SetImageList(self.__imagelist_, wx.IMAGE_LIST_SMALL)
self.__last_check_ = None
# created the columns
self.InsertColumn(0, "Index", width=75)
self.InsertColumn(1, "Name", width=100)
self.InsertColumn(2, "Sex", width=150)
self.InsertColumn(3, "Status", width=150)
# --------------------------------------------------
# Print the status of the pressed checkbox
# --------------------------------------------------
def OnCheckItem(self, index, flag):
print(index, flag)
# added the listmix.ColumnSorterMixin to do the sort function
class TestFrame(wx.Frame, listmix.ColumnSorterMixin):
def __init__(self, parent, id):
self.frame = wx.Frame.__init__(self, parent, id, 'Sample List', size=(600, 500))
self.panel = wx.Panel(self, wx.ID_ANY)
self.list = TestVirtualList(self.panel)
self.list.foundList = {}
self.sortList = []
self.readButton = wx.Button(self.panel, -1, "Get Sort List")
self.readButton.SetMaxSize((25,300))
self.Bind(wx.EVT_BUTTON, self.onGetSortList, self.readButton)
self.execButton = wx.Button(self.panel, -1, "Execute")
self.execButton.SetMaxSize((25,300))
self.Bind(wx.EVT_BUTTON, self.onExecution, self.execButton)
# put the musicdata into the foundList
# the foundlist is same with the itemDataMap
items = musicdata.items()
index = 0
for key, data in items:
self.list.InsertStringItem(index, str(key))
self.list.SetStringItem(index, 1, str(data[0]))
self.list.SetStringItem(index, 2, str(data[1]))
#self.list.SetStringItem(index, 3, str(data[2]))
self.list.SetItemData(index, key)
self.list.CheckItem(index)
tmpNode = {key:(str(index+1),str(data[0]), str(data[1]))}
self.list.foundList.update(tmpNode)
index += 1
# need added the itemDataMap due to use the ColumnSorterMixin
self.itemDataMap = self.list.foundList
listmix.ColumnSorterMixin.__init__(self, 3)
self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick, self.list)
buttonHbox = wx.BoxSizer(wx.HORIZONTAL)
buttonHbox.Add(self.readButton, 1, wx.LEFT)
buttonHbox.Add(self.execButton, 1, wx.LEFT)
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.vbox.Add(self.list, 1, wx.EXPAND)
self.vbox.Add(buttonHbox)
self.panel.SetSizer(self.vbox)
# --------------------------------------------------
# Used by the ColumnSorterMixin
# --------------------------------------------------
def GetListCtrl(self):
return self.list
# --------------------------------------------------
# Used by the ColumnSorterMixin
# --------------------------------------------------
def OnColClick(self, event):
event.Skip()
# --------------------------------------------------
# Return customSorter
# --------------------------------------------------
def GetColumnSorter(self):
return self.CustColumnSorter
# --------------------------------------------------
# Sorted the list
# --------------------------------------------------
def CustColumnSorter(self, key1, key2):
print "==========", key1, key2, "=========="
col = self._col
ascending = self._colSortFlag[col]
item1 = self.itemDataMap[key1][col]
item2 = self.itemDataMap[key2][col]
print "col:", col, " ascending", ascending, " item1:",item1," item2:",item2
#if str(item1).isdigit() and str(item2).isdigit():
if int(col) == 0:
print "1"
# sort digital value
cmpVal = cmp(int(item1), int(item2))
else:
print "2"
# sort string
cmpVal = locale.strcoll(str(item1), str(item2))
# If the items are equal then pick something else to make the sort value unique
if cmpVal == 0:
cmpVal = cmp(*self.GetSecondarySortValues(col, key1, key2))
if ascending:
print "val:",cmpVal
return cmpVal
else:
print "val:",-cmpVal
return -cmpVal
# --------------------------------------------------
# Get the sorted list
# --------------------------------------------------
def onGetSortList(self, event):
# list table already sorted, but itemDataMap didn't sorted
# get the item text at every row to grab the sorted list
self.sortList = []
# get the item text and compared with itemDataMap
for idx in range(len(self.itemDataMap)):
if self.list.IsChecked(idx):
item = self.list.GetItem(idx, 0)
findIdx = item.Text
for getIdx in range(len(self.itemDataMap)):
if self.itemDataMap[getIdx+1][0] == findIdx:
s = self.itemDataMap[getIdx+1][1]
self.sortList.append(s)
print self.sortList
# --------------------------------------------------
# call a thread to check the item
# --------------------------------------------------
def onExecution(self, event):
self.thread = ExecutionThread(self)
self.thread.start()
if __name__ == '__main__':
app = wx.PySimpleApp()
f = TestFrame(None, id=1)
f.Show()
app.MainLoop()
由於Html的編碼問題,所以source code中有兩個地方請複製下方的code覆蓋。def getUncheckData():
return zlib.decompress(
"x\xda\xeb\x0c\xf0s\xe7\xe5\x92\xe2b``\xe0\xf5\xf4p\t\x02\xd2\x02 \xcc\xc1\
\x06$\xe5?\xffO\x04R,\xc5N\x9e!\x1c@P\xc3\x91\xd2\x01\xe4\xbb{\xba8\x86X\xf4\
&\xa7\xa4$\xa5-`1\x08\\2\xbb\xb1\xb1\x91\xf5\xd8\x84o\xeb\xff\xfaw\x1d[.=[2\
\x90'\x01\x08v\xec]\xd3\xa3qvU`l\x81\xd9\xd18\t\xd3\x84+\x0cll[\xa6t\xcc9\
\xd4\xc1\xda\xc3<O\x9a1\xc3\x88\xc3j\xfa\x86_\xee@#\x19<]\xfd\\\xd69%4\x01\
\x00\xdc\x80-\x05" )
def getCheckData():
return zlib.decompress(
'x\xda\xeb\x0c\xf0s\xe7\xe5\x92\xe2b``\xe0\xf5\xf4p\t\x02\xd2\x02 \xcc\xc1\
\x06$\xe5?\xffO\x04R,\xc5N\x9e!\x1c@P\xc3\x91\xd2\x01\xe47{\xba8\x86X\xf4&\
\xa7\xa4$\xa5-`1\x08\\2\xbb\xb1\xb1\x91\xf5\xd8\x84o\xeb\xff\xfaw\x1d[.=[2\
\x90\'\x01\x08v\xec\\2C\xe3\xec+\xc3\xbd\x05fG\xe3\x14n1\xcc5\xad\x8a8\x1a\
\xb9\xa1\xeb\xd1\x853-\xaa\xc76\xecb\xb8i\x16c&\\\xc2\xb8\xe9Xvbx\xa1T\xc3U\
\xd6p\'\xbd\x85\x19\xff\xbe\xbf\xd7\xe7R\xcb`\xd8\xa5\xf8\x83\xe1^\xc4\x0e\
\xa1"\xce\xc3n\x93x\x14\xd8\x16\xb0(\x15q)\x8b\x19\xf0U\xe4\xb10\x08V\xa8\
\x99\xf3\xdd\xde\xad\x06t\x0e\x83\xa7\xab\x9f\xcb:\xa7\x84&\x00\xe0HE\xab' )
希望有幫助到你們!
Vcietocio-so Gary High https://wakelet.com/wake/TQ-9lVDeSx1BRxM5_3yU1
回覆刪除carsingwhisfi