二十二、Gtk4-ListView

news2024/11/28 14:53:26

GTK 4添加了新的列表对象GtkListView、GtkGridView和GtkColumnView。这个新特性在Gtk API参考—列表小构件概述中有描述。

GTK 4还有其他实现列表的方法。它们是GtkListBox和GtkTreeView,它们是从GTK 3接管的。在Gtk开发博客中有一篇关于Matthias Clasen所写的列表小构件的文章。他描述了为什么开发GtkListView来取代GtkListBox和GtkTreeView。

Outline

列表是一种顺序数据结构。例如,有序字符串序列"one", “two”, “three”, "four"就是一个列表。每个元素都称为item。列表类似于数组,但在很多情况下,它是由指向列表下一项的指针实现的。它有一个起始点。因此,每个元素都可以通过索引来引用(第一元素,第二元素,…,第n个元素,…)。有两种情况。一个是从1开始的索引(以1为基数),另一个是从0开始的索引(以0为基数)。

Gio提供GListModel接口。它是一个从零开始的列表,它的元素都是相同类型的GObject后代对象,或者实现相同接口的对象。实现了GListModel的对象不是小构件。因此,列表不会直接显示在屏幕上。还有一个对象GtkListView,它是一个显示列表的小构件。列表中的项目需要连接到GtkListView中的项目。GtkListItemFactory实例将列表中的项目映射到GListView。

在这里插入图片描述

GListModel

如果你想用GListModel建立一个包含字符串的列表,例如"one", “two”, “three”, “four”,请注意,字符串不能是列表中的项。因为GListModel是GObject对象的列表,而字符串不是GObject对象。“GObject”这个词在这里的意思是“GObject类或其子类”。所以,你需要一个包装器,它是一个GObject,包含一个字符串。GtkStringObject是包装器对象,而实现了GListModel的GStringList是GtkStringObject的一个列表。还有一个是GtkDirectoryList(下面会讲到)。

  • GStringList
  • GtkDirectoryList
char *array[] = {"one", "two", "three", "four", NULL};
GtkStringList *stringlist = gtk_string_list_new ((const char * const *) array);

函数gtk_string_list_new创建一个GtkStringList对象。它的项是gtkstringgobject对象,包含字符串"one", “two”, “three"和"four”。有一些函数可以向列表中添加项或从列表中删除项。

  • gtk_string_list_append将一个元素添加到列表
  • gtk_string_list_remove从列表表删除一个元素
  • gtk_string_list_get_string取得列表中的一个字符串

有关更多信息,请参阅GTK 4 API参考——GtkStringList。

其他列表对象将在后面解释。

用xml格式创建GStringList模型。

<object class="GtkDropDown">
  <property name="model">
    <object class="GtkStringList">
      <items>
        <item translatable="yes">test1</item>
        <item translatable="yes">test2</item>
        <item translatable="yes">test3</item>
      </items>
    </object>
  </property>
  <binding name="selected">
    <lookup name="out1" type="VpfCameraList">
      <lookup name="item">GtkListItem</lookup>
    </lookup>
  </binding>
</object>

GtkSelectionModel

GtkSelectionModel是一个支持选择的接口。有了这个模型,用户可以通过点击来选择项目。它由GtkMultiSelection、GtkNoSelection和GtkSingleSelection对象实现。这三个对象通常足以构建应用程序。它们是用GListModel创建的。你也可以单独创建它们,然后添加一个GListModel。

  • GtkMultiSelection支持多选。
  • GtkNoSelection不支持选择。当需要GtkSelectionModel时,它是GListModel的包装器。
  • GtkSingleSelection支持单选。
GtkNoSelection *gtk_no_selection_new (GListModel *model);
GtkSingleSelection *gtk_single_selection_new (GListModel *model);
GtkMultiSelection *gtk_multi_selection_new (GListModel *model);

GtkListView

GtkListView是一个显示GListModel item的构件。GtkListView使用GtkListItem表示列表模型中的项。但是,GtkListItem本身不是一个构件,因此用户需要将一个构件(例如GtkLabel)设置为GtkListItem的子构件,以显示list模型的一个项目。GtkListItem的"item"属性指向一个属于list模型的对象。
在这里插入图片描述
如果物品的数量非常大,例如超过1000个,GtkListItem会被回收并连接到另一个新显示的物品。这种循环使得gtklisttem对象的数量相当少,小于200。这对于抑制内存消耗的增长非常有效,因此GListModel可以包含很多元素,例如超过100万个元素。

每一项item都是一个独立的GtkListItem,下面例子中就是一个GtkListView中有四个Item(GtkListItem)

GtkListItemFactory

GtkListItemFactory创建或回收GtkListItem,并将其连接到list model的一个item。这个工厂有两个子类,GtkSignalListItemFactory和GtkBuilderListItemFactory。

GtkSignalListItemFactory

GtkSignalListItemFactory为用户提供配置gtklisttitem对象的信号。有四个信号。

  • 发出“setup”是为了设置GtkListItem对象。用户在处理程序中设置它的子部件。例如,创建一个GtkLabel部件并将gtklisttitem的child属性设置为它。即使gtklisttitem实例被回收(用于绑定到GListModel的另一项),这个设置也会保持不变。
  • "bind"是为了将列表模型中的项绑定到小部件上。例如,用户从GtkListItem实例的"item"属性中获取物品。然后获取该项的字符串,并使用该字符串设置GtkLabel实例的label属性。当GtkListItem新创建、回收或列表项发生某些更改时,就会发出此信号。
  • "unbind"是为了解除一个元素的绑定。用户在信号处理程序中撤销第2步中所做的一切。如果在第2步中创建了一些对象,那么它们必须被销毁。
  • “teardown”用来撤销第一步中完成的所有操作。因此,必须销毁步骤1中创建的widget。在这个信号之后,list元素将被销毁。

下面的程序list1.c给出了字符串"one"、“two”、"three"和"four"的列表。使用GtkNoSelection,因此用户不能选择任何项目。

 1 #include <gtk/gtk.h>
 2 
 3 static void
 4 setup_cb (GtkSignalListItemFactory *self, GtkListItem *listitem, gpointer user_data) {
 5   GtkWidget *lb = gtk_label_new (NULL);
 6   gtk_list_item_set_child (listitem, lb);
 7   /* Because gtk_list_item_set_child sunk the floating reference of lb, releasing (unref) isn't necessary for lb. */
 8 }
 9 
10 static void
11 bind_cb (GtkSignalListItemFactory *self, GtkListItem *listitem, gpointer user_data) {
12   GtkWidget *lb = gtk_list_item_get_child (listitem);
13   /* Strobj is owned by the instance. Caller mustn't change or destroy it. */
14   GtkStringObject *strobj = gtk_list_item_get_item (listitem);
15   /* The string returned by gtk_string_object_get_string is owned by the instance. */
16   gtk_label_set_text (GTK_LABEL (lb), gtk_string_object_get_string (strobj));
17 }
18 
19 static void
20 unbind_cb (GtkSignalListItemFactory *self, GtkListItem *listitem, gpointer user_data) {
21   /* There's nothing to do here. */
22 }
23 
24 static void
25 teardown_cb (GtkSignalListItemFactory *self, GtkListItem *listitem, gpointer user_data) {
26   /* There's nothing to do here. */
27   /* GtkListItem instance will be destroyed soon. You don't need to set the child to NULL. */
28 }
29 
30 static void
31 app_activate (GApplication *application) {
32   GtkApplication *app = GTK_APPLICATION (application);
33   GtkWidget *win = gtk_application_window_new (app);
34   gtk_window_set_default_size (GTK_WINDOW (win), 600, 400);
35   GtkWidget *scr = gtk_scrolled_window_new ();
36   gtk_window_set_child (GTK_WINDOW (win), scr);
37 
38   char *array[] = {
39     "one", "two", "three", "four", NULL
40   };
41   /* sl is owned by ns */
42   /* ns and factory are owned by lv. */
43   /* Therefore, you don't need to care about their destruction. */
44   GtkStringList *sl =  gtk_string_list_new ((const char * const *) array);
45   GtkNoSelection *ns =  gtk_no_selection_new (G_LIST_MODEL (sl));
46 
47   GtkListItemFactory *factory = gtk_signal_list_item_factory_new ();
48   g_signal_connect (factory, "setup", G_CALLBACK (setup_cb), NULL);
49   g_signal_connect (factory, "bind", G_CALLBACK (bind_cb), NULL);
50   /* The following two lines can be left out. The handlers do nothing. */
51   g_signal_connect (factory, "unbind", G_CALLBACK (unbind_cb), NULL);
52   g_signal_connect (factory, "teardown", G_CALLBACK (teardown_cb), NULL);
53 
54   GtkWidget *lv = gtk_list_view_new (GTK_SELECTION_MODEL (ns), factory);
55   gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), lv);
56   gtk_window_present (GTK_WINDOW (win));
57 }
58 
59 /* ----- main ----- */
60 #define APPLICATION_ID "com.github.ToshioCP.list1"
61 
62 int
63 main (int argc, char **argv) {
64   GtkApplication *app;
65   int stat;
66 
67   app = gtk_application_new (APPLICATION_ID, G_APPLICATION_DEFAULT_FLAGS);
68 
69   g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);
70 
71   stat =g_application_run (G_APPLICATION (app), argc, argv);
72   g_object_unref (app);
73   return stat;
74 }

文件list1.c位于目录src/misc下。请在下面创建一个shell脚本并将其保存到bin目录,例如$HOME/bin。

gcc `pkg-config --cflags gtk4` $1.c `pkg-config --libs gtk4`

将当前目录更改为包含list1.c和type的目录,如下所示。

$ chmod 755 $HOME/bin/comp # or chmod 755 (your bin directory)/comp
$ comp list1
$ ./a.out

在这里插入图片描述
这个程序并不难。如果您感到有些困难,请再次阅读本节,特别是GtkSignalListItemFactory小节。

GtkBuilderListItemFactory

GtkBuilderListItemFactory是另一个gtklisttitemfactory。其行为是用ui文件定义的。

<interface>
  <template class="GtkListItem">
    <property name="child">
      <object class="GtkLabel">
        <binding name="label">
          <lookup name="string" type="GtkStringObject">
            <lookup name="item">GtkListItem</lookup>
          </lookup>
        </binding>
      </object>
    </property>
  </template>
</interface>

模板标签用于定义GtkListItem。它的子属性是GtkLabel对象。工厂看到这个模板并创建GtkLabel并设置GtkListItem的子属性。这与GtkSignalListItemFactory的设置处理程序所做的相同。

然后,将GtkLabel的label属性绑定到gtkstringgobject的string属性。string对象引用GtkListItem的item属性。所以,lookup标签是这样的:

label <- string <- GtkStringObject <- item <- GtkListItem

最后一个查找标签有一个内容GtkListItem。通常,像GtkListItem这样的C类型不会出现在标签的内容中。这是一个特例。Matthias Clasen在GTK开发博客中有解释。

请记住,ui模板中的classname (GtkListItem)用作“this”指针,指向正在实例化的对象。

因此,在求值时,使用GtkListItem实例作为lookup标记的this对象。这个对象将在第后面章节解释。

C语言源代码如下。其名称是list2.c,位于src/misc目录下。

 1 #include <gtk/gtk.h>
 2 
 3 char *
 4 get_file_name (GtkListItem *item, GFileInfo *info) {
 5   return G_IS_FILE_INFO (info) ? g_strdup (g_file_info_get_name (info)) : NULL;
 6 }
 7 
 8 static void
 9 app_activate (GApplication *application) {
10   GtkApplication *app = GTK_APPLICATION (application);
11   gtk_window_present (gtk_application_get_active_window(app));
12 }
13 
14 static void
15 app_startup (GApplication *application) {
16   GtkApplication *app = GTK_APPLICATION (application);
17   GtkWidget *win = gtk_application_window_new (app);
18   gtk_window_set_default_size (GTK_WINDOW (win), 600, 400);
19   GtkWidget *scr = gtk_scrolled_window_new ();
20   gtk_window_set_child (GTK_WINDOW (win), scr);
21 
22   GFile *file = g_file_new_for_path (".");
23   GtkDirectoryList *dl = gtk_directory_list_new ("standard::name", file);
24   g_object_unref (file);
25   GtkNoSelection *ns = gtk_no_selection_new (G_LIST_MODEL (dl));
26 
27   const char *ui_string =
28 "<interface>"
29   "<template class=\"GtkListItem\">"
30     "<property name=\"child\">"
31       "<object class=\"GtkLabel\">"
32         "<binding name=\"label\">"
33           "<closure type=\"gchararray\" function=\"get_file_name\">"
34             "<lookup name=\"item\">GtkListItem</lookup>"
35           "</closure>"
36         "</binding>"
37       "</object>"
38     "</property>"
39   "</template>"
40 "</interface>"
41 ;
42   GBytes *gbytes = g_bytes_new_static (ui_string, strlen (ui_string));
43   GtkListItemFactory *factory = gtk_builder_list_item_factory_new_from_bytes (NULL, gbytes);
44 
45   GtkWidget *lv = gtk_list_view_new (GTK_SELECTION_MODEL (ns), factory);
46   gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), lv);
47 }
48 
49 /* ----- main ----- */
50 #define APPLICATION_ID "com.github.ToshioCP.list3"
51 
52 int
53 main (int argc, char **argv) {
54   GtkApplication *app;
55   int stat;
56 
57   app = gtk_application_new (APPLICATION_ID, G_APPLICATION_DEFAULT_FLAGS);
58 
59   g_signal_connect (app, "startup", G_CALLBACK (app_startup), NULL);
60   g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);
61 
62   stat =g_application_run (G_APPLICATION (app), argc, argv);
63   g_object_unref (app);
64   return stat;
65 }

GtkBulderListItemFactory不需要信号处理程序。使用GtkSingleSelection,因此用户可以一次选择一个项目。

因为这是一个小程序,所以ui数据是一个字符串。

GtkDirectoryList

GtkDirectoryList是一个包含GFileInfo对象的列表模型,GFileInfo对象是某一目录下文件的信息。它使用g_file_enumerate_children_async()来获取GFileInfo对象。链表模型由gtk_directory_list_new函数创建。
ui数据(上面的xml数据)用于在运行时构建GListItem模板。GtkBuilder根据符号表查找函数get_file_name。

GtkDirectoryList *gtk_directory_list_new (const char *attributes, GFile *file);

attributes是用逗号分隔的文件属性列表。文件属性是键值对。键由命名空间和名称组成。例如,“standard::name"键是一个文件的名称。“标准”指一般档案资料。“名称”指的是文件名。下表给出了一些例子。
请添加图片描述
当前目录为”.”。下面的程序使GtkDirectoryList dl及其内容成为当前目录下的GFileInfo对象。

GFile *file = g_file_new_for_path (".");
GtkDirectoryList *dl = gtk_directory_list_new ("standard::name", file);
g_object_unref (file);

通过修改前一小节中的list2.c来编写文件列表程序并不困难。一个问题是GInfoFile没有属性。Lookup标签查找属性,因此它对于从GFileInfo对象中查找文件名是无用的。在这种情况下,闭包标签是合适的。闭包标记指定一个函数以及函数返回值的类型。

const char *
get_file_name (GtkListItem *item, GFileInfo *info) {
  return G_IS_FILE_INFO (info) ? g_strdup (g_file_info_get_name (info)) : NULL;
}
... ...
... ...

"<interface>"
  "<template class=\"GtkListItem\">"
    "<property name=\"child\">"
      "<object class=\"GtkLabel\">"
        "<binding name=\"label\">"
          "<closure type=\"gchararray\" function=\"get_file_name\">"
            "<lookup name=\"item\">GtkListItem</lookup>"
          "</closure>"
        "</binding>"
      "</object>"
    "</property>"
  "</template>"
"</interface>"
  • 字符串“gchararray”是一个类型名称。类型“gchar”是一个类型名称,它与C类型“char”相同。因此,“gchararray”是“char类型的数组”,与string类型相同。它用于获取GValue对象的类型。GValue是一个泛型值,它可以包含各种类型的值。例如,类型名可以是gboolean、gchar (char)、gint (int)、gfloat (float)、gdouble (double)、gchararray (char *)等。这些类型名是注册到类型系统的基本类型的名称。请参阅GObject教程。
  • 闭包标签有type属性和function属性。Function attribute指定函数名,type属性指定函数返回值的类型。闭包标签的内容(它位于<closure…></closure>)是函数的参数。<lookup name="item">GtkListItem</lookup>返回GtkListItem的item属性的值这将是函数的第二个参数。第一个参数总是this对象,即GListItem实例。
  • gtk_file_name函数是闭包标记的回调函数。它首先检查info参数。因为当GListItem元素无界时,它可以为NULL。如果是GFileInfo,则返回复制的文件名。因为g_file_info_get_name的返回值(文件名)是由GFileInfo对象拥有的。因此,需要复制字符串以将所有权授予调用者。绑定标签将GtkLabel的“label”属性绑定到闭包标签。

整个程序(list3.c)如下所示。该程序位于src/misc目录中。

 1 #include <gtk/gtk.h>
 2 
 3 char *
 4 get_file_name (GtkListItem *item, GFileInfo *info) {
 5   return G_IS_FILE_INFO (info) ? g_strdup (g_file_info_get_name (info)) : NULL;
 6 }
 7 
 8 static void
 9 app_activate (GApplication *application) {
10   GtkApplication *app = GTK_APPLICATION (application);
11   gtk_window_present (gtk_application_get_active_window(app));
12 }
13 
14 static void
15 app_startup (GApplication *application) {
16   GtkApplication *app = GTK_APPLICATION (application);
17   GtkWidget *win = gtk_application_window_new (app);
18   gtk_window_set_default_size (GTK_WINDOW (win), 600, 400);
19   GtkWidget *scr = gtk_scrolled_window_new ();
20   gtk_window_set_child (GTK_WINDOW (win), scr);
21 
22   GFile *file = g_file_new_for_path (".");
23   GtkDirectoryList *dl = gtk_directory_list_new ("standard::name", file);
24   g_object_unref (file);
25   GtkNoSelection *ns = gtk_no_selection_new (G_LIST_MODEL (dl));
26 
27   const char *ui_string =
28 "<interface>"
29   "<template class=\"GtkListItem\">"
30     "<property name=\"child\">"
31       "<object class=\"GtkLabel\">"
32         "<binding name=\"label\">"
33           "<closure type=\"gchararray\" function=\"get_file_name\">"
34             "<lookup name=\"item\">GtkListItem</lookup>"
35           "</closure>"
36         "</binding>"
37       "</object>"
38     "</property>"
39   "</template>"
40 "</interface>"
41 ;
42   GBytes *gbytes = g_bytes_new_static (ui_string, strlen (ui_string));
43   GtkListItemFactory *factory = gtk_builder_list_item_factory_new_from_bytes (NULL, gbytes);
44 
45   GtkWidget *lv = gtk_list_view_new (GTK_SELECTION_MODEL (ns), factory);
46   gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scr), lv);
47 }
48 
49 /* ----- main ----- */
50 #define APPLICATION_ID "com.github.ToshioCP.list3"
51 
52 int
53 main (int argc, char **argv) {
54   GtkApplication *app;
55   int stat;
56 
57   app = gtk_application_new (APPLICATION_ID, G_APPLICATION_DEFAULT_FLAGS);
58 
59   g_signal_connect (app, "startup", G_CALLBACK (app_startup), NULL);
60   g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);
61 
62   stat =g_application_run (G_APPLICATION (app), argc, argv);
63   g_object_unref (app);
64   return stat;
65 }

通常,链接器使用符号表将对象链接到可执行文件。它包括函数名及其位置。链接器通常不会在创建的可执行文件中放入符号表。但是如果给出了--export-dynamic选项,链接器会将符号表添加到可执行文件中。

为此,C编译器提供了一个选项-Wl,--export-dynamic

  • -Wl是一个C编译器选项,它将以下选项传递给链接器。
  • --export-dynamic是一个链接器选项。以下内容摘自链接器文档。“当创建动态链接的可执行文件时,将所有符号添加到动态符号表中。动态符号表是运行时动态对象可见的符号集合。”

编译然后执行

$ gcc -Wl,--export-dynamic `pkg-config --cflags gtk4` list3.c `pkg-config --libs gtk4`

你也可以制作shell脚本编译list3.c

gcc -Wl,--export-dynamic `pkg-config --cflags gtk4` $1.c `pkg-config --libs gtk4`

将这一行文件保存到文件comp中,然后将其复制到$HOME/bin并赋予其可执行权限。

$ cp comp $HOME/bin/comp
$ chmod +x $HOME/bin/comp
$ comp list3
$ ./a.out

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/335650.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vscode执行Python输出exited with code=9009 in 0.655 seconds

vscode执行Python输出exited with code9009 in 0.655 seconds 想用vscode写个脚本&#xff0c;用自己电脑配置了下vscode的python环境&#xff0c;结果点击右上角三角图标运行时却只会输出exited with code9009 in 0.655 seconds 这就不太理解了&#xff0c;我在公司时是能正…

linux性能分析 性能之巅学习笔记和内容摘录

本文只是在阅读《性能之巅》的过程中&#xff0c;对一些觉得有用的地方进行的总结和摘录&#xff0c;并附加一些方便理解的材料&#xff0c;完整内容还请阅读Gregg的大作 概念和方法 性能分析领域一词的全栈代表了整个操作系统的软硬件在内的所有事物 软件生命周期和性能规划…

LabWindows CVI 2017开发笔记--串口API

参考资料&#xff1a;https://download.csdn.net/download/Stark_/87424565?spm1001.2014.3001.5501 转载请注明出处&#xff1a;https://blog.csdn.net/Stark_/article/details/128966962?spm1001.2014.3001.5501 打开串口OpenComConfig OpenComConfig 打开一个串行并进行…

HTML-CSS-js教程

HTML 双标签<html> </html> 单标签<img> html5的DOCTYPE声明 <!DOCTYPE html>html的基本骨架 <!DOCTYPE html> <html> </html>head标签 用于定义文档的头部。文档的头部包含了各种属性和信息&#xff0c;包括文档的标题&#…

【成为架构师课程系列】架构设计中的核心思维方法

架构设计中的核心思维方法 目录 前言 #一、抽象思维 #二、分层思维 #三、分治思维 #四、演化思维 #五、如何培养架构设计思维

leaflet 加载WKT数据(示例代码050)

第050个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中加载WKT文件,将图形显示在地图上。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果; 注意如果OpenStreetMap无法加载,请加载其他来练习 文章目录 示例效果配置方式示例源代码(共67行…

中国特色地流程管理系统,天翎让流程审批更简单

编者按&#xff1a;本文分析了国内企业在采购流程管理系统常遇到的一些难点&#xff0c;并从适应中国式流程管理模式的特点出发&#xff0c;介绍了符合中国特色的流程审批管理系统——天翎流程管理系统。关键词&#xff1a;可视化开发&#xff0c;拖拽建模&#xff0c;审批控制…

威联通ContainerStation部署Oracle11g

文章目录前言部署过程详解使用docker-compose文件创建容器临时开启NAS的SSH远程访问通过SSH客户端远程连接NAS进入容器创建用户拷贝容器中的数据库相关文件至宿主机在ContainerStation中修改docker-compose文件总结前言 ContainerStation本质上是对Docker可视化的一款软件&…

聊聊分布式锁——Redis和Redisson的方式

一、什么是分布式锁 分布式~~锁&#xff0c;要这么念&#xff0c;首先得是『分布式』&#xff0c;然后才是『锁』 分布式&#xff1a;这里的分布式指的是分布式系统&#xff0c;涉及到好多技术和理论&#xff0c;包括CAP 理论、分布式存储、分布式事务、分布式锁... 分布式系统…

Android开发

前言&#xff1a;因为这学期选了手机APP开发这门课&#xff0c;所以还是写个博客记录一下学习过程&#xff0c;包括安卓开发和ios开发。用到的资料包括课程PPT&#xff0c;和我在网上找的一些视频和资料。 1.Andriod入门 XML&#xff1a;描绘应用界面 &#xff08;决定APP长什…

NeurIPS/ICLR/ICML AI三大会国内高校和企业近年中稿量完整统计

点击文末公众号卡片&#xff0c;找对地方&#xff0c;轻松参会。 近日&#xff0c;有群友转发了一张网图&#xff0c;统计了近年来中国所有单位在NeurIPS、ICLR、ICML论文情况。原图如下&#xff1a; 中稿数100&#xff1a; 清华(1) 北大(2) 占比&#xff1a;22.6%。 累计数…

基于注解管理Bean

一、介绍从 Java 5 开始&#xff0c;Java 增加了对注解&#xff08;Annotation&#xff09;的支持&#xff0c;它是代码中的一种特殊标记&#xff0c;可以在编译、类加载和运行时被读取&#xff0c;执行相应的处理。开发人员可以通过注解在不改变原有代码和逻辑的情况下&#x…

全板电镀与图形电镀,到底有什么区别?

衔接上文&#xff0c;继续为朋友们分享普通单双面板的生产工艺流程。 如图&#xff0c;第四道主流程为电镀。 电镀的目的为&#xff1a; 适当地加厚孔内与板面的铜厚&#xff0c;使孔金属化&#xff0c;从而实现层间互连。 至于其子流程&#xff0c;可以说是非常简单&#x…

黑马】后台管理176-183

一、新建订单管理的分支二、创建一个订单管理的vue文件进行组件页面的路由配置import Order from ../components/order/Order.vue{path:/orders,component:Order},注意上面的components不要忘记少加一个s&#xff01;三&#xff0c;获取后台数据面包屑导航粘贴过来文本输入框&a…

手写MySQL补充章(十二)SQL语法解析之语法树

目录 模块分析 AST节点类型 SQL词法解析 举个例子 之前写的在第九章写的sql解析太简单了&#xff0c;SQL规范还有复杂的开闭括号以及嵌套查询&#xff0c;复杂SQL几乎不可能通过字符串匹配来实现。 本章以Druid SQL Parser解析SQL为例&#xff0c;进行分析。 模块分析 D…

如何做好需求管理?经验方法、模型、工具

需求管理能力是衡量产品经理能力的一个重要指标。因为需求是产品的基石&#xff0c;只有选取恰当的方法进行需求分析及管理&#xff0c;才能更好的构建产品方案&#xff0c;从而输出精准的产品定义。结合本人学习和自身经验&#xff0c;打算将需求管理分”需求挖掘”、”需求分…

102.第十九章 MySQL数据库 -- MySQL的备份和恢复(十二)

5.备份和恢复 5.1 备份恢复概述 5.1.1 为什么要备份 灾难恢复:硬件故障、软件故障、自然灾害、黑客攻击、误操作测试等数据丢失场景 参考链接: https://www.toutiao.com/a6939518201961251359/ 5.1.2 备份类型 完全备份,部分备份 完全备份:整个数据集 部分备份:只备份数…

shell的环境变量

一、什么是环境变量 环境变量由系统提前创建的&#xff0c;不仅在Shell编程方面&#xff0c;而且在Linux系统管理方面&#xff0c;都起着非常重要的作用。 打个比方&#xff0c;我们平时所用的编程语言如c语言&#xff0c;我们都会碰到变量的作用域的问题。比如在函数中 定义的…

新的一年软件测试行业的趋势能够更好?

如果说&#xff0c;2022年对于全世界来说&#xff0c;都是一场极大的挑战的话&#xff1b;那么&#xff0c;2023年绝对是机遇多多的一年。众所周知&#xff0c;随着疫情在全球范围内逐步得到控制&#xff0c;无论是国际还是国内的环境&#xff0c;都会呈现逐步回升的趋势&#…

【Redis高级-集群分片】

单机安装Redis首先需要安装Redis所需要的依赖&#xff1a;yum install -y gcc tclRedis安装包上传到虚拟机的任意目录&#xff1a;我放到了/tmp目录&#xff1a;解压缩&#xff1a;tar -zxvf /tmp/redis-6.2.4.tar.gz -C /tmp解压后&#xff1a;进入redis目录&#xff1a;cd /t…