我有一个GtkTreeView
具有两列文本类型(例如G_TYPE_STRING
),我使用GtkCellRendererText
来呈现列。如何将悬停效果添加到GtkTreeView单元格
是否有任何为什么我可以在鼠标进入并离开特定单元格时作出反应,然后悬停或突出显示单元格。
例如,我想在鼠标输入时在单元格渲染器中为文本添加下划线,以便提供一个视觉线索,指出可以单击该单元格以执行操作。
我有一个GtkTreeView
具有两列文本类型(例如G_TYPE_STRING
),我使用GtkCellRendererText
来呈现列。如何将悬停效果添加到GtkTreeView单元格
是否有任何为什么我可以在鼠标进入并离开特定单元格时作出反应,然后悬停或突出显示单元格。
例如,我想在鼠标输入时在单元格渲染器中为文本添加下划线,以便提供一个视觉线索,指出可以单击该单元格以执行操作。
有相当来完成任务的几种方法。下面有几个例子,用水平线分隔。
最简单的,而且在某些方面是最好的,选择是简单地将鼠标光标更改为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"));
这样,鼠标指针会在视图中的所有行的手指,不包括标题行。
GDK3文档中列出了您可以使用的一组游标名称(而不是上面的"pointer"
)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
属性取决于被呈现的文本单元是也prelit(鼠标悬停)或不:
#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);
}
如果再更换您gtk_cell_render_text_new()
与custom_cell_render_text_new()
(和改变GtkCellRenderText *
到CustomCellRenderText *
)在GtkTreeVi ew代码,您在GtkTreeView中悬停的行将变为下划线。
请注意,您将鼠标悬停在该行中的所有单元格将被突出显示,而不仅仅是细胞/列鼠标悬停。这是因为在GtkTreeView中,行(或索引)是被操纵的单位(而不是特定列上的特定单元格)。
如果您仅对GtkTreeView中的某些列使用上述渲染器,则即使将鼠标悬停在该行的某个其他列上,这些列中的文本也会加下划线。
另请注意,如果您不希望所有行都显示可点击性,则可以在数据模型中添加第三列 - 名称"sensitive"
,类型G_TYPE_BOOLEAN
,用于gboolean类型;值TRUE
如果行是可点击,FALSE
如果行是不可点击 - 在custom_cell_renderer_text_render()
的if
子句更改为
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属性关联。
如果存在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)
@lanoxx:什么是你的意图与非功能编辑的示例代码?所显示的代码经过测试可以正常工作,并且您的更改没有提供功能差异,那么它们的目的是什么? (我发现编辑尝试*可疑*,说实话,所以我想请在这里澄清一下。) –
为搞砸代码清单道歉。我试图重新格式化它,以避免必须左右滚动。在我看来,这将使代码列表更加可读。使用两种'G_DECLARE_FINAL_TYPE'或'的G_DECLARE_DERIVABLE_TYPE'也使上市更短,因为你不需要在上面定义的6个宏,并根据您使用这两个宏,你可以省略一些'结构的'声明。 – lanoxx
顺便说一句。我不认为这除了是必要的:**(并更改GtkCellRenderText *至* CustomCellRenderText)在GtkTreeView代码,**,因为自定义渲染器的新功能实际上返回一个'GtkCellRenderer'实例。 – lanoxx