9

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

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

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

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

  1. 如何以上述方式更改选择颜色而不会闪烁?
  2. 我可以通过在行周围只有一个边框来更改显示选择吗?

注意:我知道这违反了用户选择的主题。我觉得我有一个很好的理由。用颜色表示优先级可以立即识别。选择颜色隐藏了这一点。如果您有其他建议,我愿意接受,但它需要保持用户可以轻松识别优先级。

4

5 回答 5

4

您可以使用这里描述的方法——我已经对其进行了简单的测试,它可以在没有闪烁的情况下完成工作。基本上,诀窍是使用单元格渲染器的“标记”属性。但是有一个问题:如果您想使用此方法更改背景颜色,则仅更改“实际”文本后面的背景,而不是整行。但是,如果您想更改文本颜色(使用 <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;
        }
    }
}
于 2012-03-03T17:55:13.657 回答
2

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

要使用颜色填充方法来实现这一点:

  1. 根据 Tobias 的建议禁用内置突出显示(“使 STATE_SELECTED 颜色与 STATE_NORMAL 相同”)。
  2. 创建一个基于gtk.gdk.Pixbuf它的小部件允许您创建一个纯色区域,也许使用该fill方法。
  3. 使用CellRendererPixbuf作为“选择”单元格。

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

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

于 2010-06-23T08:06:32.950 回答
0

不知道你说的闪烁是什么意思。边框需要子类化 TreeView。

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

您可能已经为您的优先级执行此操作,因此只需将颜色与某些内容相乘以突出显示一行。

于 2010-06-23T07:38:38.057 回答
0

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

GTK C# 中的示例:

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

于 2020-02-05T10:07:22.070 回答
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
    }
    ...
    
于 2017-03-20T13:47:28.500 回答