我有一个GtkTreeView
,其中包含两列文字类型(例如G_TYPE_STRING
),我正在使用GtkCellRendererText
来呈现该列。
当鼠标进入并离开某个细胞然后悬停或突出显示细胞时,有什么可以反应的原因。
例如,我希望在鼠标输入时为单元格渲染器中的文本加下划线,以便提供可以单击单元格以执行操作的直观线索。
答案 0 :(得分:2)
如果PRELIT标志存在,您可以创建自定义CellRendererText并设置下划线属性。
我只知道Python:
class My_CellRendererText( Gtk.CellRendererText ):
def __init__( self ):
super().__init__()
def do_render( self, cr, widget, background_area, cell_area, flags ):
self.props.underline = ( ( flags & Gtk.CellRendererState.PRELIT ) != 0 )
return Gtk.CellRendererText.do_render( self, cr, widget, background_area, cell_area, flags )
GObject.type_register( My_CellRendererText )
答案 1 :(得分:1)
有很多方法可以完成任务。下面是几个例子,用水平线分隔。
最简单的,在某些方面最好的选项是在GtkTreeView中简单地将鼠标光标更改为手指(与指向链接时在浏览器中看到的鼠标光标相同)。
让我们说GtkTreeView *view
是我们感兴趣的观点。在之后您拨打了gtk_widget_show_all(window);
,您可以致电
GdkWindow *win = gtk_tree_view_get_bin_window(GTK_TREE_VIEW(view));
GdkDisplay *disp = gdk_window_get_display(win);
gdk_window_set_cursor(win, gdk_cursor_new_from_name(disp, "pointer"));
这样,鼠标指针将成为视图中所有行的手指,不包括标题行。
您可以使用的光标名称集(而不是上面的"pointer"
)在GDK3文档中列出了here。
缺点是如果树视图或分隔符行中有空行,鼠标指针仍然看起来像手指那样。
您可以通过应用特定于应用程序的CSS悬停颜色来覆盖悬停颜色,例如
GtkTreeView:hover {
color: #ff0000;
}
与例如
GtkCssProvider *css_provider;
css_provider = gtk_css_provider_new();
if (gtk_css_provider_load_from_data(css_provider,
"GtkTreeView:hover {\n"
" color: #ff0000;\n"
"}\n"
"", -1, NULL))
gtk_style_context_add_provider_for_screen(gdk_screen_get_default(),
GTK_STYLE_PROVIDER(css_provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
g_object_unref(css_provider);
创建主窗口后。 (当然,您可以在CSS片段中包含所有特定于应用程序的CSS覆盖。)
但是,至少在gtk + 3.18.9上,渲染器似乎不支持text-decoration
或font
CSS属性。 (GtkCssProvider似乎根本不支持cursor
属性,以防你想知道。)
此外,由于这基本上覆盖了用户主题,并且Gtk +用户可能使用了许多可能的主题,因此以这种方式更改颜色在所有主题中看起来不太好。
如果您的GtkTreeView *view;
包含可点击的行,并且您不需要选择任何内容(也就是说,您没有单独的按钮或导致操作应用的内容对于GtkTreeView中的所有选定行,您只需将选择设置为跟随鼠标光标:
gtk_tree_view_set_hover_selection(view, TRUE);
这会导致您悬停的行被选中,因此也会突出显示。您可能还希望一次将选择限制为一行:
gtk_tree_selection_set_mode(gtk_tree_view_get_selection(view),
GTK_SELECTION_SINGLE);
作为Herbalist already mentioned,您可以创建一个自定义GtkCellRendererText派生词,它会更改PangoUnderline underline
属性,具体取决于正在呈现的文本单元格是否也是预照明(悬停):
#include <gtk/gtk.h>
#define CUSTOM_TYPE_CELL_RENDERER_TEXT (custom_cell_renderer_text_get_type())
#define CUSTOM_CELL_RENDERER_TEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), CUSTOM_TYPE_CELL_RENDERER_TEXT, CustomCellRendererText))
#define CUSTOM_CELL_RENDERER_TEXT_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls), CUSTOM_TYPE_CELL_RENDERER_TEXT, CustomCellRendererTextClass))
#define CUSTOM_IS_CELL_RENDERER_TEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), CUSTOM_TYPE_CELL_RENDERER_TEXT))
#define CUSTOM_IS_CELL_RENDERER_TEXT_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls), CUSTOM_TYPE_CELL_RENDERER_TEXT))
#define CUSTOM_CELL_RENDERER_TEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), CUSTOM_TYPE_CELL_RENDERER_TEXT, CustomCellRendererTextClass))
GType custom_cell_renderer_text_get_type(void) G_GNUC_CONST;
typedef struct {
GtkCellRendererText renderer;
} CustomCellRendererText;
typedef struct {
GtkCellRendererTextClass parent_class;
} CustomCellRendererTextClass;
G_DEFINE_TYPE(CustomCellRendererText, custom_cell_renderer_text, GTK_TYPE_CELL_RENDERER_TEXT);
void custom_cell_renderer_text_render(GtkCellRenderer *cell,
cairo_t *cr,
GtkWidget *widget,
const GdkRectangle *backarea,
const GdkRectangle *cellarea,
GtkCellRendererState state)
{
if (state & GTK_CELL_RENDERER_PRELIT) {
const PangoUnderline prelit = PANGO_UNDERLINE_SINGLE;
PangoUnderline curr;
g_object_get(cell, "underline", &curr, NULL);
g_object_set(cell, "underline", prelit, NULL);
((GtkCellRendererClass *)custom_cell_renderer_text_parent_class)->render(cell, cr, widget, backarea, cellarea, state);
g_object_set(cell, "underline", curr, NULL);
} else
((GtkCellRendererClass *)custom_cell_renderer_text_parent_class)->render(cell, cr, widget, backarea, cellarea, state);
}
void custom_cell_renderer_text_class_init(CustomCellRendererTextClass *cls)
{
((GtkCellRendererClass *)cls)->render = custom_cell_renderer_text_render;
return;
}
void custom_cell_renderer_text_init(CustomCellRendererText *renderer)
{
return;
}
GtkCellRenderer *custom_cell_renderer_text_new(void)
{
return g_object_new(CUSTOM_TYPE_CELL_RENDERER_TEXT, NULL);
}
如果您在GtkTreeView代码中将gtk_cell_render_text_new()
替换为custom_cell_render_text_new()
(并将GtkCellRenderText *
更改为CustomCellRenderText *
),则您在GtkTreeView中悬停的行将加下划线
请注意,您悬停在行中的所有单元格都会突出显示,而不仅仅是您悬停在其上的单元格/列。这是因为在GtkTreeView中,行(或索引)是被操作的单元(而不是特定列上的特定单元格)。
如果您仅将上述渲染器用于GtkTreeView中的某些列,则即使鼠标悬停在该行上的某些其他列上,这些列中的文本也会加下划线。
另请注意,如果您不希望所有行都表示可点击性,则可以在数据模型中添加第三列 - 名称"sensitive"
,键入G_TYPE_BOOLEAN
以获取gboolean类型;如果该行可点击,则为TRUE
;如果该行不可点击,则为FALSE
- 并将if
中的custom_cell_renderer_text_render()
子句更改为
const GtkStateFlags flags = gtk_cell_renderer_get_state(cell, widget, state);
if ((state & GTK_CELL_RENDERER_PRELIT) &&
!(flags & GTK_STATE_FLAG_INSENSITIVE)) {
Gtk +会正常呈现带TRUE
的行,带有FALSE
的行作为分隔符或禁用文本,因为模型中的列名称会自动与同名的GtkCellRenderer属性相关联。