wx.lib.gizmos.treelistctrl.TreeListCtrl -> TR_FULL_ROW_HIGHLIGHT not working like described
Operating system: WIN64 / LIN64 wxPython version & source: 4.1.1 / 4.0.7 Python version & source: 3.8 / 3.7
Description of the problem: At wxpython2.8 TR_FULL_ROW_HIGHLIGHT colors the full row as desribed in the help -> https://docs.wxpython.org/wx.lib.gizmos.treelistctrl.TreeListCtrl.html?highlight=treelist#wx.lib.gizmos.treelistctrl.TreeListCtrl
TR_FULL_ROW_HIGHLIGHT | 0x2000 | Use this style to have the background colour and the selection highlight extend over the entire horizontal row of the tree control window.
At 4.x this does not work anymore, only the background of the text of the given cell is colored. See modified example of the demos below.
I think i found the problem in the code -> see hypertreelist.py@2972
elif drawItemBackground:
pass
# We have to colour the item background for each column separately
# So it is better to move this functionality in the subsequent for loop.
else:
dc.SetTextForeground(colText)
If I revert the code to 2.8 and change it slightly it works again:
elif drawItemBackground:
itemrect = wx.Rect(0, item.GetY() + off_h, total_w-1, total_h - off_h)
dc.SetBrush(wx.Brush(colBg, wx.SOLID))
# mod: DrawRectangle instead of DrawRectangleRect
dc.DrawRectangle(itemrect)
dc.SetTextForeground(colText)
else:
dc.SetTextForeground(colText)
Thanks for your work! BR Roland
Code Example (click to expand)
import wx
import wx.lib.gizmos as gizmos # Formerly wx.gizmos in Classic
import images
#----------------------------------------------------------------------
class TestPanel(wx.Panel):
def __init__(self, parent, log):
self.log = log
wx.Panel.__init__(self, parent, -1)
self.Bind(wx.EVT_SIZE, self.OnSize)
self.tree = gizmos.TreeListCtrl(self, -1, style=0, agwStyle=
gizmos.TR_DEFAULT_STYLE
#| gizmos.TR_HAS_BUTTONS
#| gizmos.TR_TWIST_BUTTONS
| gizmos.TR_ROW_LINES
| gizmos.TR_COLUMN_LINES
#| gizmos.TR_NO_LINES
#| gizmos.TR_LINES_AT_ROOT
| gizmos.TR_FULL_ROW_HIGHLIGHT
)
isz = (16,16)
il = wx.ImageList(isz[0], isz[1])
fldridx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, isz))
fldropenidx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, isz))
fileidx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, isz))
smileidx = il.Add(images.Smiles.GetBitmap())
self.tree.SetImageList(il)
self.il = il
# create some columns
self.tree.AddColumn("Main column")
self.tree.AddColumn("Column 1")
self.tree.AddColumn("Column 2")
self.tree.SetMainColumn(0) # the one with the tree in it...
self.tree.SetColumnWidth(0, 175)
self.root = self.tree.AddRoot("The Root Item")
self.tree.SetItemText(self.root, "col 1 root", 1)
self.tree.SetItemText(self.root, "col 2 root", 2)
self.tree.SetItemImage(self.root, fldridx, which = wx.TreeItemIcon_Normal)
self.tree.SetItemImage(self.root, fldropenidx, which = wx.TreeItemIcon_Expanded)
for x in range(15):
txt = "Item %d" % x
child = self.tree.AppendItem(self.root, txt)
self.tree.SetItemText(child, txt + "(c1)", 1)
self.tree.SetItemText(child, txt + "(c2)", 2)
self.tree.SetItemImage(child, fldridx, which = wx.TreeItemIcon_Normal)
self.tree.SetItemImage(child, fldropenidx, which = wx.TreeItemIcon_Expanded)
for y in range(5):
txt = "item %d-%s" % (x, chr(ord("a")+y))
last = self.tree.AppendItem(child, txt)
self.tree.SetItemText(last, txt + "(c1)", 1)
self.tree.SetItemText(last, txt + "(c2)", 2)
self.tree.SetItemImage(last, fldridx, which = wx.TreeItemIcon_Normal)
self.tree.SetItemImage(last, fldropenidx, which = wx.TreeItemIcon_Expanded)
for z in range(5):
txt = "item %d-%s-%d" % (x, chr(ord("a")+y), z)
item = self.tree.AppendItem(last, txt)
self.tree.SetItemText(item, txt + "(c1)", 1)
self.tree.SetItemText(item, txt + "(c2)", 2)
self.tree.SetItemImage(item, fileidx, which = wx.TreeItemIcon_Normal)
self.tree.SetItemImage(item, smileidx, which = wx.TreeItemIcon_Selected)
# set color for first cell
self.tree.SetItemBackgroundColour(item, wx.Colour(240, 167, 167))
self.tree.Expand(self.root)
self.tree.GetMainWindow().Bind(wx.EVT_RIGHT_UP, self.OnRightUp)
self.tree.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnActivate)
def OnActivate(self, evt):
self.log.write('OnActivate: %s' % self.tree.GetItemText(evt.GetItem()))
def OnRightUp(self, evt):
pos = evt.GetPosition()
item, flags, col = self.tree.HitTest(pos)
if item:
self.log.write('Flags: %s, Col:%s, Text: %s' %
(flags, col, self.tree.GetItemText(item, col)))
def OnSize(self, evt):
self.tree.SetSize(self.GetSize())
#----------------------------------------------------------------------
def runTest(frame, nb, log):
win = TestPanel(nb, log)
return win
#----------------------------------------------------------------------
overview = """<html><body>
<h2><center>TreeListCtrl</center></h2>
The TreeListCtrl is essentially a wx.TreeCtrl with extra columns,
such that the look is similar to a wx.ListCtrl.
</body></html>
"""
if __name__ == '__main__':
#raw_input("Press enter...")
import sys,os
import run
run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
Not quite sure what you're talking about, it seems to work correctly for me. Can you include a picture of what you're seeing?
Hi,
of course:
Here is a small demo to clarify:
Code Example (click to expand)
import wx
import wx.lib.agw.hypertreelist as hypertreelist
import wx.gizmos as gizmos
import random
class MyFrame(wx.Frame):
def __init__(self, tree_type):
wx.Frame.__init__(self, None, wx.ID_ANY)
# Contains a HyperTreeList
if wx.version().startswith("4"):
if tree_type.startswith("hyper"):
tree = hypertreelist.HyperTreeList(self, -1, style=0, agwStyle=hypertreelist.TR_DEFAULT_STYLE | hypertreelist.TR_HIDE_ROOT |
hypertreelist.TR_FULL_ROW_HIGHLIGHT | hypertreelist.TR_ROW_LINES |
hypertreelist.TR_COLUMN_LINES)
else:
tree = gizmos.TreeListCtrl(self, -1, style=0, agwStyle=gizmos.TR_DEFAULT_STYLE | gizmos.TR_HIDE_ROOT | gizmos.TR_FULL_ROW_HIGHLIGHT |
gizmos.TR_ROW_LINES | gizmos.TR_COLUMN_LINES)
else:
if tree_type.startswith("hyper"):
tree = hypertreelist.HyperTreeList(self, -1, style=0, agwStyle=wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT |
wx.TR_FULL_ROW_HIGHLIGHT | wx.TR_ROW_LINES |
wx.TR_HAS_VARIABLE_ROW_HEIGHT | wx.TR_NO_LINES |
wx.TR_COLUMN_LINES)
else:
tree = gizmos.TreeListCtrl(self, -1, style=wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT | wx.TR_FULL_ROW_HIGHLIGHT |
wx.TR_ROW_LINES | wx.TR_COLUMN_LINES)
col_count = 10
for i in range(col_count):
tree.AddColumn("Column "+str(i))
tree.SetMainColumn(0)
root = tree.AddRoot("The root item")
for i in range(2):
child = tree.AppendItem(root, "platform "+str(i))
for i in range(50):
tree.SetItemBackgroundColour(child, wx.Colour(240, 167, 167))
child_child = tree.AppendItem(child, "job "+str(i))
for col in range(col_count):
tree.SetItemText(child_child, str(random.randrange(10)), col+1)
for i in range(2):
tree.AppendItem(child_child, "diff "+str(i))
if __name__ == '__main__':
app = wx.App(False)
mainwin = MyFrame("hyper")
#mainwin = MyFrame("gizmos")
mainwin.Show(True)
mainwin.SetSize((1100, 800))
app.MainLoop()
wxpython2.8 - all cells are colors:

wxpython4.1.1 - only text of first cell is colored:

Of course, I can loop over all columns and set the background color by hand for each cell, but the help tells: TR_FULL_ROW_HIGHLIGHT | 0x2000 | Use this style to have the background colour and the selection highlight extend over the entire horizontal row of the tree control window.
You could also adapt the help, but keep in mind, that looping can be very slow for thousands of cells. If this behavior is too hidden, extracting the functionality to a "SetItemBackgroundColourForRow(item)" would be fine?
Hope this helps & BR Roland
Hi Roland, I have the same problem as you. In addition, wx.TR_MULTIPLE no longer has any effect in wxpython4.x.x. wx-3.0-msw works correctly. No changes in the code. I have been working with wx.TreeListCtrl for over 10 years.
I hope for a solution and remain with best regards Eckhardt
This seems to be a misunderstanding with the addition of the TR_FILL_WHOLE_COLUMN_BACKGROUND feature.
See PR #1338 and resulting bugfix PR #1389
I suppose the ideal behavior would be to fill the entire background if the TR_FULL_ROW_HIGHLIGHT flag is set, but not if the TR_FILL_WHOLE_COLUMN_BACKGROUND flag is also set.
@senior-py-developer I don't see an issue with TR_MULTIPLE for gizmos.treelistctrl. It seems to work fine in the demo and I can select multiple items. Can you file a separate bug with an example?
@cbeytas Sorry, I hadn't found the TreeListCtrl in the demo. The problem was that I used style = wx.TR_MULTIPLE instead of agwstyle = gizmos.TR_MULTIPLE. Now it works again. I will not create an issue because of this.
Could you test if the pull request fixes the highlight and behaves as you expect now?
Hi,
I tested your request and it works like expected! Thank you very much!
BR Roland