Ubuntu22.04 gnome-builder gnome C 应用程序习练笔记(二)

news2024/9/23 1:30:16

gnome-builder创建的程序,在工程树中有三个重要程序:main主程序、application应用程序和window主窗口程序。main整个程序的起始,它会操作application生产应用环境,application会操作window生成主窗口,于是就有了 application 和 window 的 handle,驾驭整个程序的运行。

新的主窗口生成,主要改动 withcambla-window.c 的内容,其它的暂时先不用动。

1- 改动窗体结构,将用到的widget全部放入窗体结构中(初创时只有个label)。

struct _WithcamblaWindow
{
  GtkApplicationWindow  parent_instance;

  /* Template widgets */
  GtkHeaderBar        *header_bar;
  GtkLabel            *label1;
  GtkButton           *button1;
  GtkButton           *button2;
  GtkButton           *button3;
  GtkGrid             *grid1;
};

2- 将widget绑定到template上

static void
withcambla_window_class_init (WithcamblaWindowClass *klass)
{
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);

  gtk_widget_class_set_template_from_resource (widget_class, "/org/mongnewer/test/withcambla-window.ui");
  gtk_widget_class_bind_template_child (widget_class, WithcamblaWindow, header_bar);
  gtk_widget_class_bind_template_child (widget_class, WithcamblaWindow, label1);
  gtk_widget_class_bind_template_child (widget_class, WithcamblaWindow, button1);
  gtk_widget_class_bind_template_child (widget_class, WithcamblaWindow, button2);
  gtk_widget_class_bind_template_child (widget_class, WithcamblaWindow, button3);
  gtk_widget_class_bind_template_child (widget_class, WithcamblaWindow, grid1);
}

3- 在窗口初始化中加入widget控制信号,建立起widget事件关系。

static void
withcambla_window_init (WithcamblaWindow *self)
{
  gtk_widget_init_template (GTK_WIDGET (self));


  g_signal_connect(GTK_BUTTON(self->button1), "clicked", G_CALLBACK(on_button1_click), self);
  g_signal_connect(GTK_BUTTON(self->button2), "clicked", G_CALLBACK(on_button2_click), self);
  g_signal_connect(GTK_BUTTON(self->button3), "clicked", G_CALLBACK(on_button3_click), self);
}

至此,主窗口程序就改动好了。

button1_click回调函数,在label上显示 hello 字样,因主使用markup, 不需要 pango 了。

static void
on_button1_click(GtkWidget *widget, WithcamblaWindow *self)
{
  gtk_label_set_markup (GTK_LABEL(self->label1),
                       "<span foreground='red' underline='single' underline_color='blue' font_desc='Times italic 48'>Hello!</span>");

  GtkWidget *inlabel = gtk_button_get_child(GTK_BUTTON(self->button1));
  gtk_label_set_markup (GTK_LABEL(inlabel),
                       "<span foreground='red' underline='single' underline_color='blue' font_desc='Times italic 48'>Hello!</span>");
}

button2_click回调函数,用程序方式直接写出一个窗体并作为主窗体的子窗体显示。

static void
on_button2_click(GtkWidget *widget, GtkWindow *self)
{
  GtkWidget *window = gtk_window_new ();
  gtk_window_set_default_size (GTK_WINDOW(window), 600, 400);
  gtk_window_set_title (GTK_WINDOW(window), "A popup window by button_click");
  GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
  gtk_box_set_homogeneous (GTK_BOX(box), TRUE);
  gtk_window_set_child (GTK_WINDOW(window), GTK_WIDGET(box));
  GtkWidget *button = gtk_button_new_with_label("Pressed!");
  gtk_widget_set_visible (GTK_WIDGET(button), TRUE);

  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(closewindow), window);
  g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(closewindow), window);

  GtkWidget *spacer1 = gtk_label_new("");
  gtk_box_append (GTK_BOX(box), GTK_WIDGET(spacer1));
  gtk_box_append (GTK_BOX(box), GTK_WIDGET(button));
  GtkWidget *spacer2 = gtk_label_new("");
  gtk_box_append (GTK_BOX(box), GTK_WIDGET(spacer2));

  gtk_window_set_resizable (GTK_WINDOW(window), FALSE);
  gtk_window_set_modal (GTK_WINDOW(window), TRUE);

  gtk_window_set_transient_for (GTK_WINDOW(window), GTK_WINDOW(self));
  gtk_widget_set_visible(window, TRUE);
}

button3_click回调函数,产生一个TEST_TYPE_WINDOW定义的子窗口并作为主窗口的子窗口显示。它不是由程序代码实现的,而是由 ui 文件实现的,需要另外的popwindowf.h和popwindowf.c实现。如果只是简单窗口,这种方式比直接代码实现窗口显得啰嗦一些。

static void
on_button3_click(GtkWidget *widget, GtkWindow *self)
{
  GtkWindow *window;
    window = g_object_new (TEST_TYPE_WINDOW,
                           "default-height", 550, "default-width", 800,
                           "title", "Nice window!",
                           NULL);

  gtk_window_set_transient_for (window, self);
  gtk_window_present (window);
}

代码实现的子窗口

ui实现的子窗口(直接改了一下主窗口的ui,它们看上去很相似)

七、用菜单命令操作实现上述两个子窗口

菜单项操作与button信号操作有些不同,首先在主窗口的ui中加上新的菜单项。app.ghello, app.popwin1, app.popwin2

  <menu id="primary_menu">
    <section>
      <item>
        <attribute name="action">app.preferences</attribute>
        <attribute name="label" translatable="yes">_Preferences</attribute>
      </item>
      <item>
        <attribute name="action">win.show-help-overlay</attribute>
        <attribute name="label" translatable="yes">_Keyboard Shortcuts</attribute>
      </item>
      <item>
        <attribute name="action">app.about</attribute>
        <attribute name="label" translatable="yes">_About gnomeapp</attribute>
      </item>
      <item>
        <attribute name="action">app.ghello</attribute>
        <attribute name="label" translatable="yes">_gPrint Hello</attribute>
      </item>
      <item>
        <attribute name="action">app.popwin</attribute>
        <attribute name="label" translatable="yes">_popup window</attribute>
      </item>
      <item>
        <attribute name="action">app.popwin1</attribute>
        <attribute name="label" translatable="yes">_popup window 1</attribute>
      </item>
      <item>
        <attribute name="action">app.popwin2</attribute>
        <attribute name="label" translatable="yes">_popup window 2</attribute>
      </item>
    </section>
  </menu>

菜单项的操作是withcambla-application.c初始化时关联的,它们都要挂到action map上去,然后与回调函数建立联系,快捷键也是在这个地方关联的。

static void
withcambla_application_init (WithcamblaApplication *self)
{
  g_autoptr (GSimpleAction) quit_action = g_simple_action_new ("quit", NULL);
  g_signal_connect_swapped (quit_action, "activate", G_CALLBACK (g_application_quit), self);
  g_action_map_add_action (G_ACTION_MAP (self), G_ACTION (quit_action));

  g_autoptr (GSimpleAction) about_action = g_simple_action_new ("about", NULL);
  g_signal_connect (about_action, "activate", G_CALLBACK (withcambla_application_show_about), self);
  g_action_map_add_action (G_ACTION_MAP (self), G_ACTION (about_action));

  g_autoptr (GSimpleAction) ghello_action = g_simple_action_new ("ghello", NULL);
  g_signal_connect (ghello_action, "activate", G_CALLBACK (ghello), self);
  g_action_map_add_action (G_ACTION_MAP (self), G_ACTION (ghello_action));

  g_autoptr (GSimpleAction) popwin_action = g_simple_action_new ("popwin", NULL);
  g_signal_connect (popwin_action, "activate", G_CALLBACK (popwin), self);
  g_action_map_add_action (G_ACTION_MAP (self), G_ACTION (popwin_action));

  g_autoptr (GSimpleAction) popwin1_action = g_simple_action_new ("popwin1", NULL);
  g_signal_connect (popwin1_action, "activate", G_CALLBACK (popwin1), self);
  g_action_map_add_action (G_ACTION_MAP (self), G_ACTION (popwin1_action));

  g_autoptr (GSimpleAction) popwin2_action = g_simple_action_new ("popwin2", NULL);
  g_signal_connect (popwin2_action, "activate", G_CALLBACK (popwin2), self);
  g_action_map_add_action (G_ACTION_MAP (self), G_ACTION (popwin2_action));

  gtk_application_set_accels_for_action (GTK_APPLICATION (self),
                                         "app.ghello",
                                         (const char *[]) {
                                           "<Control><Super><Alt>h",
                                           NULL,
                                         });

  gtk_application_set_accels_for_action (GTK_APPLICATION (self),
                                         "app.quit",
                                         (const char *[]) {
                                           "<primary>q",
                                           NULL,
                                         });
}

popwin回调函数,用代码创建子窗体,可以用button创建的好个,习练时也可以考贝一个改一下用。

static void
popwin(GSimpleAction *action,
        GVariant     *parameter,
        gpointer      user_data)
{
  WithcamblaApplication *self = WITHCAMBLA_APPLICATION (user_data);
  GtkWindow *windowapp = gtk_application_get_active_window (GTK_APPLICATION (self));
  GtkWidget *window = gtk_window_new ();
  gtk_window_set_default_size (GTK_WINDOW(window), 600, 400);
  gtk_window_set_title (GTK_WINDOW(window), "A popup window called from Menu");
  //gtk_window_set_application (GTK_WINDOW(window), GTK_APPLICATION (self));
  GtkWidget *box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
  gtk_box_set_homogeneous (GTK_BOX(box), TRUE);
  gtk_window_set_child (GTK_WINDOW(window), GTK_WIDGET(box));
  GtkWidget *button = gtk_button_new_with_label("A new button");
  gtk_widget_set_visible (GTK_WIDGET(button), TRUE);

  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(closewindow), window);
  g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(closewindow), window);

  GtkWidget *spacer1 = gtk_label_new("");
  gtk_box_append (GTK_BOX(box), GTK_WIDGET(spacer1));
  gtk_box_append (GTK_BOX(box), GTK_WIDGET(button));
  GtkWidget *spacer2 = gtk_label_new("");
  gtk_box_append (GTK_BOX(box), GTK_WIDGET(spacer2));

  gtk_window_set_resizable (GTK_WINDOW(window), FALSE);
  gtk_window_set_modal (GTK_WINDOW(window), TRUE);

  gtk_window_set_transient_for (GTK_WINDOW(window), GTK_WINDOW(windowapp));
  gtk_widget_set_visible(window, TRUE);
}

popwin1回调函数是通过测试调用一个子过程,由子过程代码创建的子窗口。

static void
popwin1(GSimpleAction *action,
        GVariant     *parameter,
        gpointer      user_data)
{
  WithcamblaApplication *self = WITHCAMBLA_APPLICATION (user_data);
  GtkWindow *windowapp = gtk_application_get_active_window (GTK_APPLICATION (self));
  popwinsub(NULL, windowapp);
}

popwin2回调函数,是调用popwindowf.h和popwindowf.c程序实现的。

static void
popwin2(GSimpleAction *action,
        GVariant      *parameter,
        gpointer       user_data)
{
  WithcamblaApplication *self = WITHCAMBLA_APPLICATION (user_data);
  GtkWindow *windowapp = gtk_application_get_active_window (GTK_APPLICATION (self));

  //popwinsubf(NULL, windowapp);
  /* Get the current window or create one if necessary. */

  GtkWindow *window;
    window = g_object_new (TEST_TYPE_WINDOW,
                           "default-height", 550, "default-width", 800,
                           "title", "Nice window!",
                           NULL);

  gtk_window_set_transient_for (window, windowapp);

  /* Ask the window manager/compositor to present the window. */
  gtk_window_present (window);
}

还有些内容写在下篇笔记中

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

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

相关文章

【前端模板】bootstrap5披萨餐厅网站Pizza King平台(电商适用,附源码)

一、需求分析 披萨餐厅网站是指由披萨餐厅创建和维护的在线平台&#xff0c;旨在提供与该餐厅相关的信息和服务。以下是一些常见的功能和内容&#xff0c;可以在披萨餐厅网站上找到&#xff1a; 餐厅介绍&#xff1a;网站通常会提供有关餐厅的背景信息&#xff0c;包括其历史、…

VMwawre配置静态ip

1、查看当前虚拟机网关&#xff08;记住这个网关&#xff0c;后面使用&#xff09; 2、进入目录命令&#xff1a;cd /etc/sysconfig/network-scripts/ 3、编辑网卡配置文件命令&#xff1a;vim ifcfg-ens33 4、配置静态IP&#xff0c;修改和增加如下信息&#xff1a; 修改的内…

Vue3编写简单的App组件(二)

一、Vue3页面渲染基本流程 1、入口文件 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><link rel"icon" href"/favicon.ico"><meta name"viewport" content"widthde…

vivo发布2023 年度科技创新;阿里全新AI代理,可模拟人类操作手机

vivo 发布 2023 年度十大产品技术创新 近日&#xff0c;vivo 发布了「2023 年度科技创新」十大产品技术创新榜单&#xff0c;并将这些技术分为了 4 个板块。 「四大蓝科技」为 vivo 在去年推出的全新技术品牌&#xff0c;涵盖蓝晶芯片技术栈、蓝海续航系统、蓝心大模型、蓝河操…

【Linux】Shell编程

Shell编程 目录 Shell编程1.shell基础1.输入重定向 & 输出重定向2.管道3.特殊字符(3.1)通配符(3.2)引号(3.3)注释符(#) 4.别名5.命令历史history 2.Shell脚本Shell脚本的执行方式(1)为脚本文件加上可执行权限,然后在命令行直接输入shell脚本文件名执行。(2)sh shell脚本名(…

redis之布隆过滤

目录 1、redis之布隆过滤 2、布隆过滤器原理 3、布隆过滤器使用步骤 初始化bitmap 添加占坑位 判断是否存在圜 1、redis之布隆过滤 布隆过滤&#xff1a;有一个初值都为0的bit数组和多个哈希函数构成&#xff0c;用来快速判断集合中是否存在某个元素。目的&#xff1a;减…

【深度学习】pytorch 与 PyG 安装(pip安装)

【深度学习】pytorch 与 PyG 安装&#xff08;pip安装&#xff09; 一、PyTorch安装和配置&#xff08;一&#xff09;、安装 CUDA&#xff08;二&#xff09;、安装torch、torchvision、torchaudio三个组件&#xff08;1&#xff09;下载镜像文件&#xff08;2&#xff09;创建…

华为第二批难题五:AI技术提升六面体网格生成自动化问题

有CAE开发商问及OCCT几何内核的网格方面的技术问题。其实&#xff0c;OCCT几何内核的现有网格生成能力比较弱。 HybridOctree_Hex的源代码&#xff0c;还没有仔细去学习。 “HybridOctree_Hex”的开发者说&#xff1a;六面体网格主要是用在数值模拟领域的&#xff0c;比如汽车…

智慧自助餐饮系统(SpringBoot+MP+Vue+微信小程序+JNI+ncnn+YOLOX-Nano)

一、项目简介 本项目是配合智慧自助餐厅下的一套综合系统&#xff0c;该系统分为安卓端、微信小程序用户端以及后台管理系统。安卓端利用图像识别技术进行识别多种不同菜品&#xff0c;识别成功后安卓端显示该订单菜品以及价格并且生成进入小程序的二维码&#xff0c;用户扫描…

Kubernetes基础(十五)-k8s网络通信

1 k8s网络类型 2 Pod网络 2.1 同一pod内不同容器通信 Pod是Kubernetes中最小的可部署单元&#xff0c;它是一个或多个紧密关联的容器的组合&#xff0c;这些容器共享同一个网络命名空间和存储卷&#xff0c;因此Pod中的所有容器都共享相同的网络命名空间和IP地址——PodIP&a…

JavaScript实现轮播图方法

效果图 先来看下效果图&#xff0c;嫌麻烦就不用具体图片来实现了&#xff0c;主要是理清思路。&#xff08;自动轮播&#xff0c;左右按钮切换图片&#xff0c;小圆点切换图片&#xff0c;鼠标移入暂停轮播&#xff0c;鼠标移出继续轮播&#xff09; HTML 首先是html内容&am…

获取视频帧图片

在实现了minio文件上传的基础上进行操作 一、编写pom <dependency><groupId>org.jcodec</groupId><artifactId>jcodec</artifactId><version>0.2.5</version> </dependency> <dependency><groupId>org.jcodec<…

Modern C++ 内存篇1 - allocator

1. 前言 从今天起我们开始内存相关的话题&#xff0c;内存是个很大的话题&#xff0c;一时不知从何说起。内存离不开allocator&#xff0c;我们就从allocator开始吧。allocator目前有两种&#xff1a;std::allocator, std::pmr::polymorphic_allocator&#xff0c;各有优缺点。…

中小型网络系统总体规划与设计方法

目录 1.基于网络的信息系统基本结构 2.网络需求调研与系统设计原则 3.网络用户调查 4.网络节点地理位置分布情况 5.网络需求详细分析 6.应用概要分析 7.网络工程设计总体目标与设计原则 8.网络结构与拓扑构型设计方法 9.核心层网络结构设计 10.接入核心路由器 11.汇聚…

寒假作业2024.2.8

1.现有文件test.c\test1.c\main.c,请编写Makefile Makefile文件&#xff1a; CCgcc EXEfile OBJS$(patsubst %.c,%.o,$(wildcard *.c)) CFLAGS-c -o all:$(EXE)file:test.o test1.o main.o$(CC) $^ -o $%.o:%.c$(CC) $(CFLAGS) $ $^.PHONY:clean clean:rm $(OBJS)main.c文件:…

Codeforces Round 260 (Div. 1)A. Boredom(dp)

最开始写了一发贪心wa了&#xff0c;然后这种选和不选的组合优化问题&#xff0c;一般是考虑动态规划 d p [ i ] [ 0 ] &#xff1a; dp[i][0]&#xff1a; dp[i][0]&#xff1a;表示第i个数不选的最大值 d p [ i ] [ 1 ] &#xff1a; dp[i][1]&#xff1a; dp[i][1]&#xf…

【LeetCode】37. 解数独(困难)——代码随想录算法训练营Day30

题目链接&#xff1a;37. 解数独 题目描述 编写一个程序&#xff0c;通过填充空格来解决数独问题。 数独的解法需 遵循如下规则&#xff1a; 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。&…

Python进阶--爬取美女图片壁纸(基于回车桌面网的爬虫程序)

目录 一、前言 二、爬取下载美女图片 1、抓包分析 a、分析页面 b、明确需求 c、抓包搜寻 d、总结特点 2、编写爬虫代码 a、获取图片页网页源代码 b、提取所有图片的链接和标题 c、下载并保存这组图片 d、 爬取目录页的各种类型美女图片的链接 e、实现翻页 三、各…

TCP和UDP相关问题(重点)——8.TCP的拥塞控制怎么实现的?

在某段时间内&#xff0c;若对网络中某一资源的需求超过了该资源所能提供的可用部分&#xff0c;网络性能就会变坏&#xff0c;比如在高速公路上行驶的车辆&#xff0c;如果一时期内涌入了太多的车辆&#xff0c;道路将变得拥堵&#xff0c;交通状况变差。网络中也是一样&#…

Android 识别车牌信息

打开我们心爱的Android Studio 导入需要的资源 gradle //开源车牌识别安卓SDK库implementation("com.github.HyperInspire:hyperlpr3-android-sdk:1.0.3")button.setOnClickListener(v -> {Log.d("Test", "");try (InputStream file getAs…