Changing the selected item colour in a GtkTreeview using python

后端 未结 5 1525
别那么骄傲
别那么骄傲 2021-01-18 07:57

I have a dialog which contains a pygtk.treeview for listing tasks by priority. Each row has the background colour set based on that priority, so for example the highest prio

相关标签:
5条回答
  • 2021-01-18 08:10

    You could add a separate pixbuf cell (say, the same size as a small icon) to the far left to indicate selection. Selected rows could fill this with a more "solid" (saturated) version of the colour used for the background. For example. if you use a pink background for high priority, you could use red for the selection indicator. Or you could use an icon.

    To implement this with the colour filling method:

    1. Disable the built-in highlighting as per Tobias' suggestion ("make the STATE_SELECTED color identical to STATE_NORMAL").
    2. Create a widget based on gtk.gdk.Pixbuf that allows you to create a solid area of colour, perhaps using the fill method.
    3. Use a CellRendererPixbuf for your "selection" cell.

    You can then color or uncolour the "selection cell" upon selection changes to indicate which row is selected, or display an icon (eg. a stock symbol).

    Note that I haven't implemented this, it's just an idea. It departs significantly from the usual GTK selection indication, so (obviously) use your judgement as to whether it's useable.

    0 讨论(0)
  • 2021-01-18 08:28

    Calling both ModifyBase and ModifyText worked for me. Calling just ModifyBase changes the text color to White

    Example in GTK C#:

    treeViewList.ModifyBase(StateType.Selected, treeViewList.Style.Base(StateType.Normal)); treeViewList.ModifyText(StateType.Selected, treeViewList.Style.Text(StateType.Normal));

    0 讨论(0)
  • 2021-01-18 08:33

    You can use the method described here – I have tested it briefly and it does the job without flickering. Basically, the trick is to use the "Markup" property of the cell renderer. There's one catch, though: if you want to change the background colour with this method, only the background behind the "actual" text is changed, not the whole row. However, if you want to change the text colour (with <span foreground= ... ), which was actually my intention, it looks ok.

    I have the following CellDataFunc (this is C#, but I hope it's 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;
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-18 08:34

    Not sure what you mean by flickering. A border would require subclassing TreeView.

    I'd make the STATE_SELECTED color identical to STATE_NORMAL to disable the built-in highlighting. Then set a data_func on each column and change some color on the cell renderer depending on whether it's in the selection or not.

    You're probably already doing this for your priority, so just multiply the color with something to highlight a row.

    0 讨论(0)
  • 2021-01-18 08:35

    The question is outdated, but it is possible for someone else to be useful... For totally disabling selection and making hover effect in the tree: 1. Disable system selection in the tree:

      _treeView.Selection.Mode = SelectionMode.None;
    
    1. Handle 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 讨论(0)
提交回复
热议问题