增加搜索条

我们继续充实我们应用程序的功能。如今,我们添加搜索。GTK+在GtkSearchEntryGtksearchbar中支持这个功能。搜索条是一个可以嵌入顶端来展现搜索输入。

我们在头栏增加一个开关按钮,他可以用来滑出头栏下的搜索条。

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <interface>
  3. <!-- interface-requires gtk+ 3.8 -->
  4. <template class="ExampleAppWindow" parent="GtkApplicationWindow">
  5. <property name="title" translatable="yes">Example Application</property>
  6. <property name="default-width">600</property>
  7. <property name="default-height">400</property>
  8. <child>
  9. <object class="GtkBox" id="content_box">
  10. <property name="visible">True</property>
  11. <property name="orientation">vertical</property>
  12. <child>
  13. <object class="GtkHeaderBar" id="header">
  14. <property name="visible">True</property>
  15. <child type="title">
  16. <object class="GtkStackSwitcher" id="tabs">
  17. <property name="visible">True</property>
  18. <property name="margin">6</property>
  19. <property name="stack">stack</property>
  20. </object>
  21. </child>
  22. <child>
  23. <object class="GtkToggleButton" id="search">
  24. <property name="visible">True</property>
  25. <property name="sensitive">False</property>
  26. <style>
  27. <class name="image-button"/>
  28. </style>
  29. <child>
  30. <object class="GtkImage" id="search-icon">
  31. <property name="visible">True</property>
  32. <property name="icon-name">edit-find-symbolic</property>
  33. <property name="icon-size">1</property>
  34. </object>
  35. </child>
  36. </object>
  37. <packing>
  38. <property name="pack-type">end</property>
  39. </packing>
  40. </child>
  41. </object>
  42. </child>
  43. <child>
  44. <object class="GtkSearchBar" id="searchbar">
  45. <property name="visible">True</property>
  46. <child>
  47. <object class="GtkSearchEntry" id="searchentry">
  48. <signal name="search-changed" handler="search_text_changed"/>
  49. <property name="visible">True</property>
  50. </object>
  51. </child>
  52. </object>
  53. </child>
  54. <child>
  55. <object class="GtkStack" id="stack">
  56. <signal name="notify::visible-child" handler="visible_child_changed"/>
  57. <property name="visible">True</property>
  58. </object>
  59. </child>
  60. </object>
  61. </child>
  62. </template>
  63. </interface>

实现搜索条需要更改一点我们还没打算完成的代码。搜索实现的核心是一个监听搜索条文字变化的信号句柄。

  1. ...
  2. static void
  3. search_text_changed (GtkEntry *entry,
  4. ExampleAppWindow *win)
  5. {
  6. ExampleAppWindowPrivate *priv;
  7. const gchar *text;
  8. GtkWidget *tab;
  9. GtkWidget *view;
  10. GtkTextBuffer *buffer;
  11. GtkTextIter start, match_start, match_end;
  12. text = gtk_entry_get_text (entry);
  13. if (text[0] == '\0')
  14. return;
  15. priv = example_app_window_get_instance_private (win);
  16. tab = gtk_stack_get_visible_child (GTK_STACK (priv->stack));
  17. view = gtk_bin_get_child (GTK_BIN (tab));
  18. buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
  19. /* Very simple-minded search implementation */
  20. gtk_text_buffer_get_start_iter (buffer, &start);
  21. if (gtk_text_iter_forward_search (&start, text, GTK_TEXT_SEARCH_CASE_INSENSITIVE,
  22. &match_start, &match_end, NULL))
  23. {
  24. gtk_text_buffer_select_range (buffer, &match_start, &match_end);
  25. gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (view), &match_start,
  26. 0.0, FALSE, 0.0, 0.0);
  27. }
  28. }
  29. static void
  30. example_app_window_init (ExampleAppWindow *win)
  31. {
  32. ...
  33. gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), search_text_changed);
  34. ...
  35. }
  36. ...

(full source)

加上了搜索条,我们的应用程序现在是这样的:

getting-started-app7.png