Changing the color of a selected item in GtkTreeview using python

I have a dialog containing pygtk.treeview for setting priority tasks. Each line has a background color set based on this priority, therefore, for example, the light red background has the highest priority.

The row selection color is not so easy to change. I can set it using treeview.modify_base(gtk.STATE_SELECTED, "#C4C4C4") , but no colors will work well with the colors used to improve the concept of priority.

I had the idea to change the highlight color as a slightly darker version of the color used as the normal background of the line, so in the above example it will be a darker red. I tried calling the function above in response to the treselection changed signal, and it works, but with heavy flickering.

Another idea was to change the selection to transparent and place a border around it, but as far as I can tell, this is not possible.

  • How to change the highlight color as described above without flickering?
  • Can I change the selection display with only a border around the line?

Note. I know this violates the theme chosen by the user. I feel that I have a good reason. Having a priority indicated by color makes it instantly recognizable. The highlight color hides it. If you have alternative suggestions, I am open to them, but it should retain the ease with which the user can prioritize.

+6
python user-interface gtk pygtk gtktreeview
source share
4 answers

You can add a separate pixbuf cell (say, the same size as the small icon) to the far left to indicate the selection. Selected lines can fill this with a more โ€œsolidโ€ (saturated) version of the color used for the background. For example. if you use a pink background for high priority, you can use red for the selection indicator. Or you can use the icon.

To implement this using the color fill method:

  • Turn off the built-in backlight as suggested by Tobias ("make the STATE_SELECTED color identical to STATE_NORMAL").
  • Create a widget based on gtk.gdk.Pixbuf that allows you to create a solid region of color, possibly using fill .
  • Use CellRendererPixbuf for your cell of choice.

You can then color or parse the โ€œselection cellโ€ after changing the selection to indicate which row is selected, or display an icon (for example, a stock symbol).

Please note that I have not implemented this, this is just an idea. It differs significantly from the usual GTK selection indicator, so (obviously) use your opinion on whether it can be used.

+2
source share

You can use the method described here - I checked it briefly and it does the work without blinking. Basically, the trick is to use the Layout property of the cell renderer. However, there is one catch: if you want to change the background color using this method, only the background behind the "actual" text will change, not the entire line. However, if you want to change the color of the text (with <span foreground = ...), which was actually my intention, this looks fine.

I have the following CellDataFunc (this is C #, but I hope it is still useful):

 private void CellDataFunc(Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter) { Item item = (Item) model.GetValue (iter, 0); if(cell is CellRendererText) { int id = (int)column.GetData("colId"); string text = ""; switch(id) { case 0: text = item.Name; break; case 1: text = item.Size; break; case 2: text = item.Time.ToString(); break; } //(cell as Gtk.CellRendererText).Text = text; if(item.Highlight) { (cell as Gtk.CellRendererText).Markup = "<span background=\"red\">"+text+"</span>"; } else { (cell as Gtk.CellRendererText).Markup = text; } } } 
+1
source share

Not sure what you mean by flicker. The border will require a subclass of TreeView.

I would make the STATE_SELECTED color identical to STATE_NORMAL to disable the built-in backlight. Then set data_func for each column and change the color on the cell developer, depending on whether it is selected or not.

You may already be doing this for your priority, so just increase the color with something to highlight the line.

0
source share

The question is outdated, but someone may be useful ... To completely disable the selection and create a freezing effect in the tree: 1. Disable the system selection in the tree:

  _treeView.Selection.Mode = SelectionMode.None; 
  1. Fire the MotionNotifyEvent event:

     [ConnectBefore] private void TreeViewOnMotionNotifyEvent(object o, MotionNotifyEventArgs args) { TreePath treePath; TreeIter iter; int x = Convert.ToInt32(args.Event.X); int y = Convert.ToInt32(args.Event.Y); _treeView.GetPathAtPos(x, y, out treePath); _treeView.Model.GetIter(out iter, treePath); BindObject fieldModel = CellUtil.GetModelValue(_treeView.Model, iter, 1) as BindObject; HoverLine = _vievModel.BindObjectCollection.IndexOf(fieldModel); } 
  2. In the SetCellDataFunc method:

     BindObject fieldModel = CellUtil.GetModelValue(treeModel, iter, 1) as BindObject; int rowCount = _vievModel.BindObjectCollection.IndexOf(fieldModel); if (HoverLine == rowCount) { cellRenderer.CellBackgroundGdk = ThemeUtility.GdkOddSelectionColor; //Your selection color } else { cellRenderer.CellBackgroundGdk = ThemeUtility.SystemSelectionColor; //Your system selection color } ... 
0
source share

All Articles