GTK 4中如何用GtkDropDown实现带输入框的下拉组件
在GTK 4中实现带输入框的下拉组件(替代GTK3的GtkComboBox(has-entry=TRUE))
GTK4中GtkComboBox被弃用后,官方推荐用GtkDropDown替代,但它本身不带输入功能。要实现和gtk4-widget-factory中一致的带输入下拉效果,有两种可行方案:
方案一:官方推荐的组合式实现(GtkEntry + GtkDropDown)
通过将输入框、过滤模型和下拉组件结合,实现实时筛选+自定义输入的功能,步骤如下:
构建基础选项模型
使用GtkStringList存储下拉选项,这是GTK4原生的字符串列表模型:GtkStringList *option_list = gtk_string_list_new((const char*[]){"文档", "图片", "音频", "视频", NULL});添加过滤逻辑
用GtkStringFilter和GtkFilterListModel实现输入内容的实时筛选,设置前缀匹配并忽略大小写:GtkStringFilter *filter = gtk_string_filter_new(NULL); gtk_string_filter_set_match_mode(filter, GTK_STRING_FILTER_MATCH_MODE_PREFIX); gtk_string_filter_set_ignore_case(filter, TRUE); GtkFilterListModel *filtered_model = gtk_filter_list_model_new(G_LIST_MODEL(option_list), GTK_FILTER(filter));关联输入框与过滤器
创建GtkEntry,并将输入框的文本与过滤器的搜索字符串绑定,实现输入即筛选:GtkEntry *input_entry = gtk_entry_new(); g_object_bind_property(input_entry, "text", filter, "search", G_BINDING_SYNC_CREATE);搭建下拉弹出结构
创建GtkDropDown并关联过滤后的模型,用GtkPopover将下拉组件绑定到输入框:GtkDropDown *dropdown = gtk_drop_down_new(G_LIST_MODEL(filtered_model), NULL); GtkPopover *popover = gtk_popover_new(); gtk_popover_set_child(popover, GTK_WIDGET(dropdown)); gtk_popover_set_parent(popover, GTK_WIDGET(input_entry));处理选择与弹出逻辑
- 选中下拉选项时,同步内容到输入框并收起下拉:
static void on_dropdown_selected(GtkDropDown *dropdown, GParamSpec *pspec, GtkEntry *entry) { GtkStringObject *selected_item = gtk_drop_down_get_selected_item(dropdown); if (selected_item != NULL) { const char *item_text = gtk_string_object_get_string(selected_item); gtk_entry_set_text(entry, item_text); gtk_popover_popdown(GTK_POPOVER(gtk_widget_get_parent(GTK_WIDGET(dropdown)))); } } g_signal_connect(dropdown, "notify::selected-item", G_CALLBACK(on_dropdown_selected), input_entry); - 输入框获得焦点时弹出下拉列表:
static gboolean on_entry_focused(GtkWidget *widget, GdkEventFocus *event, GtkPopover *popover) { gtk_popover_popup(popover); return FALSE; } g_signal_connect(input_entry, "focus-in-event", G_CALLBACK(on_entry_focused), popover);
- 选中下拉选项时,同步内容到输入框并收起下拉:
方案二:兼容式快速实现(GtkComboBoxText)
虽然GtkComboBox被标记为弃用,但它的子类GtkComboBoxText目前仍可正常使用,用法和GTK3完全一致,只需开启has-entry属性:
GtkComboBoxText *combo_text = gtk_combo_box_text_new_with_entry(); // 添加选项 gtk_combo_box_text_append_text(combo_text, "文档"); gtk_combo_box_text_append_text(combo_text, "图片"); gtk_combo_box_text_append_text(combo_text, "音频"); // 获取用户输入或选中的内容 const char *content = gtk_combo_box_text_get_active_text(combo_text);
注意:该方案属于过渡兼容方案,官方未来可能会移除GtkComboBox系列组件,长期来看推荐使用方案一。
内容的提问来源于stack exchange,提问作者9-Pin
相关产品推荐
相关产品推荐

