Je souhaite que certaines lignes soient de couleur rouge au lieu de la couleur standard (bleu sur Windows) afin que je puisse indiquer l'état. Quelqu'un sait si cela est possible dans wxPython?wxPython wxListCtrl couleur de ligne sélectionnée
Répondre
Afin de faire ce que vous voulez, c'est-à-dire d'avoir une couleur de sélection différente lorsque certains éléments sont sélectionnés, vous devrez passer dans win32. Heureusement, ce n'est pas trop difficile de le faire en python. Cela rend toutefois votre plateforme de code dépendante. Je l'ai essayé aujourd'hui dans un petit programme. Si le genre n'est pas "Rock", je rends la sélection orange. Voici quelques captures d'écran.
Articles Rock sélectionnés alt text http://img26.imageshack.us/img26/981/soshot1.jpg
Articles mixtes sélectionnés. Notez que RnB et Blues sont sélectionnés avec Orange alt text http://img258.imageshack.us/img258/1307/soshot2.jpg
Voici le code. Il semble effrayant au début, mais si vous connaissez un win32, ce n'est pas si mal. J'utilise le package pywin32 et les bibliothèques std ctypes. J'ai dû définir certaines des constantes du SDK car elles n'étaient pas disponibles dans le module win32con.
import sys
import wx
import wx.lib.mixins.listctrl as listmix
import win32api
import win32gui
import win32con
import win32gui_struct
import commctrl
import ctypes
from ctypes.wintypes import BOOL, HWND, RECT, UINT, DWORD, HDC, DWORD, LPARAM, COLORREF
LVM_FIRST = 0x1000
LVM_GETSUBITEMRECT=(LVM_FIRST + 56)
LVIR_BOUNDS =0
LVIR_ICON =1
LVIR_LABEL =2
LVIR_SELECTBOUNDS =3
DEFAULT_GUI_FONT =17
#LPNMHDR
class NMHDR(ctypes.Structure):
pass
INT = ctypes.c_int
NMHDR._fields_ = [('hwndFrom', HWND), ('idFrom', UINT), ('code', INT)]
LPNMHDR = ctypes.POINTER(NMHDR)
#LPNMCUSTOMDRAW
class NMCUSTOMDRAW(ctypes.Structure):
pass
NMCUSTOMDRAW._fields_ = [('hdr', NMHDR), ('dwDrawStage', DWORD), ('hdc', ctypes.c_int),
('rc', RECT), ('dwItemSpec', DWORD), ('uItemState', UINT),
('lItemlParam', LPARAM)]
LPNMCUSTOMDRAW = ctypes.POINTER(NMCUSTOMDRAW)
#LPNMLVCUSTOMDRAW
class NMLVCUSTOMDRAW(ctypes.Structure):
pass
NMLVCUSTOMDRAW._fields_ = [('nmcd', NMCUSTOMDRAW),
('clrText', COLORREF),
('clrTextBk', COLORREF),
('iSubItem', ctypes.c_int),
('dwItemType', DWORD),
('clrFace', COLORREF),
('iIconEffect', ctypes.c_int),
('iIconPhase', ctypes.c_int),
('iPartId', ctypes.c_int),
('iStateId', ctypes.c_int),
('rcText', RECT),
('uAlign', UINT)
]
LPNMLVCUSTOMDRAW = ctypes.POINTER(NMLVCUSTOMDRAW)
musicdata = {
1 : ("Bad English", "The Price Of Love", "Rock"),
2 : ("DNA featuring Suzanne Vega", "Tom's Diner", "Rock"),
3 : ("George Michael", "Praying For Time", "Rock"),
4 : ("Gloria Estefan", "Here We Are", "Rock"),
5 : ("Linda Ronstadt", "Don't Know Much", "Rock"),
6 : ("Michael Bolton", "How Am I Supposed To Live Without You", "Blues"),
7 : ("Paul Young", "Oh Girl", "Rock"),
8 : ("Paula Abdul", "Opposites Attract", "Rock"),
9 : ("Richard Marx", "Should've Known Better", "Rock"),
10 : ("Bobby Brown", "My Prerogative", "RnB"),
}
class MyListCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin):
def __init__(self, parent, ID, pos=wx.DefaultPosition,
size=wx.DefaultSize, style=0):
wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
listmix.ListCtrlAutoWidthMixin.__init__(self)
def ShouldCustomDraw(self, row):
if self.IsSelected(row):
listitem = self.GetItem(row, 2)
genre = listitem.GetText()
return genre != "Rock"
def CustomDraw(self, lpcd):
if lpcd.contents.nmcd.dwDrawStage == commctrl.CDDS_PREPAINT:
return (True, commctrl.CDRF_NOTIFYITEMDRAW)
if lpcd.contents.nmcd.dwDrawStage == commctrl.CDDS_ITEMPREPAINT:
if self.ShouldCustomDraw(lpcd.contents.nmcd.dwItemSpec):
#do custom drawing for non Rock selected rows
#paint the selection background
color = win32api.RGB(255, 127, 0) #orange
brush = win32gui.CreateSolidBrush(color)
r = lpcd.contents.nmcd.rc
win32gui.FillRect(int(lpcd.contents.nmcd.hdc), (r.left+4, r.top, r.right, r.bottom), brush)
win32gui.DeleteObject(brush)
return (True, commctrl.CDRF_NOTIFYSUBITEMDRAW)
if lpcd.contents.nmcd.dwDrawStage == commctrl.CDDS_ITEMPREPAINT|commctrl.CDDS_SUBITEM:
row = lpcd.contents.nmcd.dwItemSpec
col = lpcd.contents.iSubItem
item = self.GetItem(row, col)
text = item.GetText()
#paint the text
rc = RECT()
rc.top = col
if col > 0:
rc.left = LVIR_BOUNDS
else:
rc.left = LVIR_LABEL
success = win32api.SendMessage(self.Handle, LVM_GETSUBITEMRECT, row, ctypes.addressof(rc))
if col > 0:
rc.left += 5
else:
rc.left += 2
rc.top += 2
if success:
oldColor = win32gui.SetTextColor(lpcd.contents.nmcd.hdc, win32gui.GetSysColor(win32con.COLOR_HIGHLIGHTTEXT))
win32gui.DrawText(lpcd.contents.nmcd.hdc, text, len(text), (rc.left, rc.top, rc.right, rc.bottom), win32con.DT_LEFT|win32con.DT_VCENTER)
win32gui.SetTextColor(lpcd.contents.nmcd.hdc, oldColor)
return (True, commctrl.CDRF_SKIPDEFAULT)
# don't need custom drawing
return (True, commctrl.CDRF_DODEFAULT)
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
wx.Frame.__init__(self, *args, **kwds)
self._sizer = wx.BoxSizer(wx.VERTICAL)
tID = wx.NewId()
self._ctl = MyListCtrl(self, tID,
style=wx.LC_REPORT
#| wx.BORDER_SUNKEN
| wx.BORDER_NONE
| wx.LC_EDIT_LABELS
| wx.LC_SORT_ASCENDING
#| wx.LC_NO_HEADER
#| wx.LC_VRULES
#| wx.LC_HRULES
#| wx.LC_SINGLE_SEL
)
self._sizer.Add(self._ctl, 1, wx.EXPAND, 3)
self.PopulateList()
self.oldWndProc = win32gui.SetWindowLong(self.GetHandle(), win32con.GWL_WNDPROC, self.MyWndProc)
def MyWndProc(self, hWnd, msg, wParam, lParam):
if msg == win32con.WM_NOTIFY:
hwndFrom, idFrom, code = win32gui_struct.UnpackWMNOTIFY(lParam)
if code == commctrl.NM_CUSTOMDRAW and hwndFrom == self._ctl.Handle:
lpcd = ctypes.cast(lParam, LPNMLVCUSTOMDRAW)
retProc, retCode = self._ctl.CustomDraw(lpcd)
if retProc:
return retCode
# Restore the old WndProc. Notice the use of wxin32api
# instead of win32gui here. This is to avoid an error due to
# not passing a callable object.
if msg == win32con.WM_DESTROY:
win32api.SetWindowLong(self.GetHandle(),
win32con.GWL_WNDPROC,
self.oldWndProc)
# Pass all messages (in this case, yours may be different) on
# to the original WndProc
return win32gui.CallWindowProc(self.oldWndProc,
hWnd, msg, wParam, lParam)
def PopulateList(self):
self._ctl.InsertColumn(0, "Artist")
self._ctl.InsertColumn(1, "Title")
self._ctl.InsertColumn(2, "Genre")
items = musicdata.items()
for key, data in items:
index = self._ctl.InsertStringItem(sys.maxint, data[0])
self._ctl.SetStringItem(index, 1, data[1])
self._ctl.SetStringItem(index, 2, data[2])
self._ctl.SetItemData(index, key)
self._ctl.SetColumnWidth(0, wx.LIST_AUTOSIZE)
self._ctl.SetColumnWidth(1, wx.LIST_AUTOSIZE)
self._ctl.SetColumnWidth(2, 100)
self.currentItem = 0
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame(None, -1, 'wxListCtrl StackOverflow')
frame.Show()
self.SetTopWindow(frame)
return 1
if __name__ == "__main__":
app = MyApp(0)
app.MainLoop()
Dans votre classe que vous tirez de wx.ListCtrl, jetez un oeil à dominante
def OnGetItemAttr(self, item):
return self.normalAttr[item % 2]
#
Lorsque les attributs d'un élément sont initialisés à l'avance en utilisant:
self.normalAttr = []
self.normalAttr.append(wx.ListItemAttr())
grayAttr = wx.ListItemAttr()
grayAttr.SetBackgroundColour(lightGray)
self.normalAttr.append(grayAttr)
Donc dans ce cas, J'alterne les couleurs d'arrière-plan par défaut, et un attribut gris clair.
Cette fonction est appelée pour chaque ligne telle qu'elle est peinte, vous pouvez donc l'utiliser pour indiquer toutes sortes de statuts. Si la ligne est sélectionnée devrait être un cas facile.
- 1. ligne sélectionnée
- 2. Conserver la dernière ligne sélectionnée de UITableView
- 3. Renvoie la couleur de fond de la cellule sélectionnée
- 4. wxPython + multitraitement: vérifier si une chaîne de couleur est légitime
- 5. dojox.Grid ligne couleur de fond
- 6. changeant la couleur sélectionnée iTMS dans une zone de liste
- 7. Modifier la cellule dans la ligne sélectionnée
- 8. Mémoriser la ligne sélectionnée dans DataGridView
- 9. Supprimer la ligne sélectionnée d'un DataGridView
- 10. supprimer ligne sélectionnée dans Gridview dans Asp.net
- 11. C# WinForms DataGridView - Ligne constante sélectionnée!
- 12. Activer/Désactiver BindingNavigatorItems en fonction de la ligne sélectionnée
- 13. Comment incrémenter une ligne de table sélectionnée sur l'iPhone
- 14. Tracer une ligne avec une couleur dégradée
- 15. Conserver la ligne actuellement sélectionnée dans un datagridview
- 16. Comment afficher la ligne GridView sélectionnée dans DetailsView
- 17. La ligne sélectionnée ne change pas après un tri GridView
- 18. C#/WPF: Get Ligne sélectionnée à partir d'un ListView
- 19. Obtenir la ligne sélectionnée dans UIPickerView pour chaque composant
- 20. C# Silverlight Datagrid - Changement de couleur de ligne
- 21. Question de formatage Excel, couleur de ligne par défaut
- 22. wxPython: Utilisation de EVT_IDLE
- 23. DataGridView SelectLine couleur à aucun?
- 24. wxpython compilation
- 25. wxPython dialogs
- 26. Condition de données Flex avancées Ligne Couleur d'arrière-plan
- 27. BIRT: Ligne en alternance Couleur dans un groupe de tableaux
- 28. Exécution wxPython
- 29. Modifier la couleur d'arrière-plan de ListView dans VB6
- 30. Réglage de la couleur de la police sélectionnée pour être différente de la couleur de la police dans le contrôle non sélectionné listbox