使用python在GtkTreeview中更改所选项目颜色

时间:2010-06-23 05:58:52

标签: python user-interface gtk pygtk gtktreeview

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

行选择颜色不容易改变。我可以使用treeview.modify_base(gtk.STATE_SELECTED, "#C4C4C4")设置它,但没有颜色可以很好地用于增强优先级概念的颜色。

我有想法将选择颜色更改为用作正常行背景的颜色的稍暗版本,因此在上面的示例中,这将是更暗的红色。我尝试调用上面的函数来响应treeselection的changed信号,它可以工作,但是闪烁很多。

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

  1. 如何在没有闪烁的情况下以上述方式更改选择颜色?
  2. 我可以通过在行周围只有一个边框来更改显示选择吗?
  3. 注意:我知道这违反了用户选择的主题。我觉得我有充分的理由。具有颜色指示的优先级使其可以立即识别。选择颜色隐藏了这一点。如果您有其他建议,我会向他们开放,但需要保留用户识别优先级的便利性。

5 个答案:

答案 0 :(得分:2)

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

使用颜色填充方法实现此目的:

  1. 根据Tobias的建议(“使STATE_SELECTED颜色与STATE_NORMAL相同”)禁用内置突出显示。
  2. 根据gtk.gdk.Pixbuf创建一个小部件,允许您使用fill方法创建一个纯色区域。
  3. 使用CellRendererPixbuf作为“选择”单元格。
  4. 然后,您可以在选择更改时对“选择单元格”进行着色或取消着色,以指示选择了哪一行,或者显示图标(例如,股票代码)。

    请注意,我还没有实现这一点,这只是一个想法。它明显偏离了通常的GTK选择指示,所以(显然)使用你的判断它是否可用。

答案 1 :(得分:1)

你可以使用描述的方法here - 我已经对它进行了简单的测试,它可以在没有闪烁的情况下完成工作。基本上,诀窍是使用单元格渲染器的“标记”属性。但是有一个问题:如果你想用这种方法改变背景颜色,只改变“实际”文本背后的背景,而不是整行。但是,如果要更改文本颜色(使用< span foreground = ...),实际上是 我的意图,看起来还不错。

我有以下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;
        }
    }
}

答案 2 :(得分:0)

不确定你的意思是闪烁。边框需要继承TreeView。

我将STATE_SELECTED颜色设置为与STATE_NORMAL相同,以禁用内置突出显示。然后在每列上设置data_func,并根据它是否在选择中更改单元格渲染器上的某种颜色。

您可能已经为优先级做了这个,所以只需将颜色与某些颜色相乘以突出显示一行。

答案 3 :(得分:0)

问题已经过时,但其他人可能会有用...... 要完全禁用选择并在树中进行悬停效果: 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
    }
    ...
    

答案 4 :(得分:0)

同时调用ModifyBase和ModifyText对我有用。仅调用ModifyBase会将文本颜色更改为白色

GTK C#中的示例:

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