代码之家  ›  专栏  ›  技术社区  ›  Jon

使用python更改GTKTreeView中所选项目的颜色

  •  6
  • Jon  · 技术社区  · 15 年前

    我有一个对话框,其中包含按优先级列出任务的pygtk.treeview。每一行都有基于该优先级的背景颜色集,例如,最高优先级的背景为浅红色。

    行选择颜色不太容易更改。我可以用 treeview.modify_base(gtk.STATE_SELECTED, "#C4C4C4") 但没有任何颜色能与用于增强优先级概念的颜色很好地配合。

    我想把选择的颜色改成一种略暗的颜色,用作普通的行背景,所以在上面的例子中,这将是一种较深的红色。我尝试调用上面的函数来响应TreeSelection的 changed 信号,它可以工作,但是有很大的闪烁。

    另一个想法是将选择更改为透明,并在其周围加上边框,但据我所知,这是不可能的。

    1. 如何在不闪烁的情况下以上述方式更改选择颜色?
    2. 我可以更改显示所选内容的方式,只在行周围加一个边框吗?

    注意:我知道这违反了用户选择的主题。我觉得我有理由这么做。有颜色表示的优先权使它能立即被识别。选择颜色隐藏了这一点。如果你有其他的建议,我可以接受,但它需要保持用户识别优先级的容易程度。

    4 回复  |  直到 8 年前
        1
  •  2
  •   detly    15 年前

    您可以在最左边添加一个单独的pixbuf单元格(例如,与一个小图标的大小相同)以指示选择。选定的行可以用背景颜色的更“纯色”(饱和)版本来填充。例如。如果使用粉色背景作为高优先级,则可以使用红色作为选择指示器。或者你可以使用一个图标。

    要使用颜色填充方法实现此功能,请执行以下操作:

    1. 根据Tobias的建议禁用内置突出显示(“使状态“选定颜色”与状态“正常”相同”)。
    2. 基于创建小部件 gtk.gdk.Pixbuf 这样你就可以创造出一个纯色的区域,也许可以使用 fill 方法。
    3. 使用A CellRendererPixbuf 对于您的“选择”单元格。

    然后,您可以在选择更改时对“选择单元格”进行着色或取消着色,以指示选择了哪一行,或者显示图标(如股票符号)。

    注意,我还没有实现这一点,这只是一个想法。它明显不同于通常的GTK选择指示,因此(很明显)使用您的判断来判断它是否可用。

        2
  •  1
  •   Community CDub    8 年前

    您可以使用描述的方法 here –我对它进行了简短的测试,它可以在不闪烁的情况下完成工作。基本上,技巧是使用单元渲染器的“标记”属性。不过,有一个要点:如果你想改变 背景 用这种方法,只改变“实际”文本后面的背景,而不是整行。但是,如果要更改 文本 颜色(具有<SPAN前景=…),实际上 我的意图,看起来不错。

    我有以下CellDataFunc(这是C,但我希望它仍然有用):

    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;
            }
        }
    }
    
        3
  •  0
  •   Tobias    15 年前

    不知道你所说的闪烁是什么意思。边界需要对TreeView进行子类化。

    我将使状态“选定颜色”与状态“正常”相同,以禁用内置突出显示。然后在每列上设置一个数据函数,并根据单元格渲染器是否在选定区域中更改一些颜色。

    你可能已经在为你的优先级做这个了,所以只要用一些东西来增加颜色来突出显示一行。

        4
  •  0
  •   seriousseruy    8 年前

    这个问题已经过时了,但其他人可能会有用… 对于完全禁用选择并在树中产生悬停效果: 1。禁用树中的系统选择:

      _treeView.Selection.Mode = SelectionMode.None;
    
    1. 处理MotionNotifyEvent事件:

      [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. 在setcelldatafunc方法中:

      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
      }
      ...