在opensuse15.6中使用gnome-builder-45.0的基本功能(五)GTK4应用程序2

一、拆分单独一整个c文件和写h文件
二、glib-compile-resources将ui文件、图片纳入到二进制执行文件gtk4player中
三、制作图标org.example.gtk4player.svg
四、改写org.example.gtk4player.desktop.in和org.example.gtk4player.metainfo.xml.in
五、使用xgettext制作po文件,将软件中的英文翻译成中文
六、将gtk4player安装到本机电脑才能看到是否有翻译成中文的效果

这是接着上一篇文章的内容:
《在opensuse15.6中使用gnome-builder-45.0的基本功能(四)GTK4应用程序》
https://blog.csdn.net/weixin_42145772/article/details/159156183?spm=1001.2014.3001.5501

一、拆分单独一整个c文件和写h文件
应用程序——编程——构建器——最下方创建新工程——工程名称org.example.gtk4player——应用程序ID:org.example.gtk4player——模板——GTK4应用程序——创建工程

应用程序——工具——终端
ruhongvnc@localhost:~/工程/gtk4player/src> pwd
/home/ruhongvnc/工程/gtk4player/src
ruhongvnc@localhost:~/工程/gtk4player/src> ls
gtk gtk4player.gresource.xml gtk4player-window.ui
gtk4player-application.c gtk4player-window.c main.c
gtk4player-application.h gtk4player-window.h meson.build

删除以下文件
gtk4player-application.c
gtk4player-application.h
gtk4player-window.c
gtk4player-window.h
gtk4player-window.ui
ruhongvnc@localhost:~/工程/gtk4player/src> rm gtk4player-application.*
ruhongvnc@localhost:~/工程/gtk4player/src> rm gtk4player-window.*
ruhongvnc@localhost:~/工程/gtk4player/src> ls
gtk gtk4player.gresource.xml main.c meson.build

原来所有代码都在单独一整个main.c文件,现在主要是为了把main函数拆分出来,共有8个函数,拆分成三个c文件main.c、gtk4player.c和callbacks.c
main.c只有main函数,内容以下:
ruhongvnc@localhost:~/工程/gtk4player/src> cat main.c

#include "config.h"

#include <glib/gi18n.h>

#include <gtk/gtk.h>
#include "gtk4player.h"

int
main (int   argc,
      char *argv[])
{
	GtkApplication *app = NULL;
	int status;

	bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
	textdomain (GETTEXT_PACKAGE);

	app = gtk_application_new ("org.example.gtk4player", G_APPLICATION_DEFAULT_FLAGS);
	g_signal_connect( app, "activate", G_CALLBACK( activate ), NULL );
	status = g_application_run (G_APPLICATION (app), argc, argv);
	g_object_unref( app );
	
	return status;
}

gtk4player.c只有activate函数,删除static单词,内容以下:
ruhongvnc@localhost:~/工程/gtk4player/src> cat gtk4player.c

#include <gtk/gtk.h>
#include "gtk4player.h"
#include "callbacks.h"
#include <glib/gi18n.h>

 GtkWidget *window = NULL;

void activate( GtkApplication *app, gpointer user_data )
{
  GtkWidget *title;
  GtkWidget *video;
  GtkWidget *button;
  GtkWidget *image;
  GtkWidget *fullscreen_button;
  GtkEventController *controller;

      window = gtk_application_window_new( app );
      gtk_window_set_title (GTK_WINDOW (window), "Video Player");
      gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
      g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);

      video = gtk_video_new ();
      gtk_video_set_autoplay (GTK_VIDEO (video), TRUE);
      gtk_window_set_child (GTK_WINDOW (window), video);

      title = gtk_header_bar_new ();
      gtk_window_set_titlebar (GTK_WINDOW (window), title);

      button = gtk_button_new_with_mnemonic ("_Open");
      g_signal_connect (button, "clicked", G_CALLBACK (open_clicked_cb), video);
      gtk_header_bar_pack_start (GTK_HEADER_BAR (title), button);

      button = gtk_button_new ();
      image = gtk_image_new_from_file ("/home/ruhongvnc/工程/video_player_gtk4meson/data/picture01.png");
      gtk_accessible_update_relation (GTK_ACCESSIBLE (image),
                                      GTK_ACCESSIBLE_RELATION_LABELLED_BY, button, NULL,
                                      -1);
      gtk_image_set_pixel_size (GTK_IMAGE (image), 24);
      gtk_button_set_child (GTK_BUTTON (button), image);
      g_signal_connect (button, "clicked", G_CALLBACK (logo_clicked_cb), video);
      gtk_accessible_update_property (GTK_ACCESSIBLE (button),
                                      GTK_ACCESSIBLE_PROPERTY_LABEL, "GTK Logo",
                                      -1);
      gtk_header_bar_pack_start (GTK_HEADER_BAR (title), button);

      button = gtk_button_new ();
      image = gtk_image_new_from_file ("/home/ruhongvnc/工程/video_player_gtk4meson/data/picture02.png");
      gtk_accessible_update_relation (GTK_ACCESSIBLE (image),
                                      GTK_ACCESSIBLE_RELATION_LABELLED_BY, button, NULL,
                                      -1);
      gtk_image_set_pixel_size (GTK_IMAGE (image), 24);
      gtk_button_set_child (GTK_BUTTON (button), image);
      g_signal_connect (button, "clicked", G_CALLBACK (bbb_clicked_cb), video);
      gtk_accessible_update_property (GTK_ACCESSIBLE (button),
                                      GTK_ACCESSIBLE_PROPERTY_LABEL, "Big Buck Bunny",
                                      -1);
      gtk_header_bar_pack_start (GTK_HEADER_BAR (title), button);

      fullscreen_button = gtk_button_new_from_icon_name ("view-fullscreen-symbolic");
      g_signal_connect (fullscreen_button, "clicked", G_CALLBACK (fullscreen_clicked_cb), NULL);
      gtk_accessible_update_property (GTK_ACCESSIBLE (fullscreen_button),
                                      GTK_ACCESSIBLE_PROPERTY_LABEL, "Fullscreen",
                                      -1);

      gtk_header_bar_pack_end (GTK_HEADER_BAR (title), fullscreen_button);

      controller = gtk_shortcut_controller_new ();
      gtk_shortcut_controller_set_scope (GTK_SHORTCUT_CONTROLLER (controller),
                                         GTK_SHORTCUT_SCOPE_GLOBAL);
      gtk_widget_add_controller (window, controller);
      gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
           gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_F11, 0),
                             gtk_callback_action_new (toggle_fullscreen, NULL, NULL)));

  gtk_window_present( GTK_WINDOW( window ) );
}

头文件 gtk4player.h只有activate函数,函数名称最后要加上英文分号,内容以下:
ruhongvnc@localhost:~/工程/gtk4player/src> cat gtk4player.h

void activate( GtkApplication *app, gpointer user_data );

其它函数全部放在callbacks.c,回调函数的英语是callback function,删除所有static单词,内容以下:
ruhongvnc@localhost:~/工程/gtk4player/src> cat callbacks.c

#include <gtk/gtk.h>
#include "callbacks.h"

 void
open_dialog_response_cb (GObject *source,
                         GAsyncResult *result,
                         void *user_data)
{
  GtkFileDialog *dialog = GTK_FILE_DIALOG (source);
  GtkWidget *video = user_data;
  GFile *file;

  file = gtk_file_dialog_open_finish (dialog, result, NULL);
  if (file)
    {
      gtk_video_set_file (GTK_VIDEO (video), file);
      g_object_unref (file);
    }
}

 void
open_clicked_cb (GtkWidget *button,
                 GtkWidget *video)
{
  GtkFileDialog *dialog;
  GtkFileFilter *filter;
  GListStore *filters;

  dialog = gtk_file_dialog_new ();
  gtk_file_dialog_set_title (dialog, "Select a video");

  filters = g_list_store_new (GTK_TYPE_FILE_FILTER);

  filter = gtk_file_filter_new ();
  gtk_file_filter_add_pattern (filter, "*");
  gtk_file_filter_set_name (filter, "All Files");
  g_list_store_append (filters, filter);
  g_object_unref (filter);

  filter = gtk_file_filter_new ();
  gtk_file_filter_add_mime_type (filter, "image/*");
  gtk_file_filter_set_name (filter, "Images");
  g_list_store_append (filters, filter);
  g_object_unref (filter);

  filter = gtk_file_filter_new ();
  gtk_file_filter_add_mime_type (filter, "video/*");
  gtk_file_filter_set_name (filter, "Video");
  g_list_store_append (filters, filter);

  gtk_file_dialog_set_default_filter (dialog, filter);
  g_object_unref (filter);

  gtk_file_dialog_set_filters (dialog, G_LIST_MODEL (filters));
  g_object_unref (filters);

  gtk_file_dialog_open (dialog,
                        GTK_WINDOW (gtk_widget_get_root (button)),
                        NULL,
                        open_dialog_response_cb, video);
}

 void
logo_clicked_cb (GtkWidget *button,
                 gpointer   video)
{
  GFile *file;

  file = g_file_new_for_uri ("file:///home/ruhongvnc/工程/video_player_gtk4meson/data/you_belong_to_me_taylor_swift.mp4");
  gtk_video_set_file (GTK_VIDEO (video), file);
  g_object_unref (file);
}

 void
bbb_clicked_cb (GtkWidget *button,
                gpointer   video)
{
  GFile *file;

  file = g_file_new_for_uri ("https://download.blender.org/peach/trailer/trailer_400p.ogg");
  gtk_video_set_file (GTK_VIDEO (video), file);
  g_object_unref (file);
}

 void
fullscreen_clicked_cb (GtkWidget *button,
                       gpointer   unused)
{
  GtkWidget *widget_window = GTK_WIDGET (gtk_widget_get_root (button));

  gtk_window_fullscreen (GTK_WINDOW (widget_window));
}

 gboolean
toggle_fullscreen (GtkWidget *widget,
                   GVariant  *args,
                   gpointer   data)
{
  GdkSurface *surface;
  GdkToplevelState state;

  surface = gtk_native_get_surface (GTK_NATIVE (widget));
  state = gdk_toplevel_get_state (GDK_TOPLEVEL (surface));

  if (state & GDK_TOPLEVEL_STATE_FULLSCREEN)
    gtk_window_unfullscreen (GTK_WINDOW (widget));
  else
    gtk_window_fullscreen (GTK_WINDOW (widget));

  return TRUE;
}

头文件 callbacks.h有6个函数,删除所有static单词,函数名称最后要加上英文分号,内容以下:
ruhongvnc@localhost:~/工程/gtk4player/src> cat callbacks.h

 void
open_dialog_response_cb (GObject *source,
                         GAsyncResult *result,
                         void *user_data);

 void
open_clicked_cb (GtkWidget *button,
                 GtkWidget *video);

 void
logo_clicked_cb (GtkWidget *button,
                 gpointer   video);

 void
bbb_clicked_cb (GtkWidget *button,
                gpointer   video);

 void
fullscreen_clicked_cb (GtkWidget *button,
                       gpointer   unused);

 gboolean
toggle_fullscreen (GtkWidget *widget,
                   GVariant  *args,
                   gpointer   data);

ruhongvnc@localhost:~/工程/gtk4player/src> ls
callbacks.c gtk gtk4player.gresource.xml main.c
callbacks.h gtk4player.c gtk4player.h meson.build

修改src文件夹下的meson.build文件,修改c文件列表,使用符号#注释关于gtk4player.gresource.xml的4行内容,不要删除,下一步会再用到,内容以下:
ruhongvnc@localhost:~/工程/gtk4player/src> cat meson.build

gtk4player_sources = [
  'main.c',
  'gtk4player.c',
  'callbacks.c',
]

gtk4player_deps = [
  dependency('gtk4'),
]

# gtk4player_sources += gnome.compile_resources('gtk4player-resources',
#   'gtk4player.gresource.xml',
#  c_name: 'gtk4player'
# )

executable('gtk4player', gtk4player_sources,
  dependencies: gtk4player_deps,
       install: true,
)

单击最上方铁锤图标旁边的倒三角图标——配置工程——左下角——org.example.gtk4player.json——位置——源码树内部——运行时——org.gnome.Sdk/x86_64/45
单击最上方铁锤图标,编译程序gtk4player

…/src/main.c:39:56: error: ‘activate’ undeclared (first use in this function)
39 | g_signal_connect( app, “activate”, G_CALLBACK( activate ), NULL );

报错未声明activate,函数activate是在gtk4player.c文件,要在main.c加上#include “gtk4player.h”

单击最上方铁锤图标,编译程序gtk4player

…/src/gtk4player.c:27:56: error: ‘open_clicked_cb’ undeclared (first use in this function)
27 | g_signal_connect (button, “clicked”, G_CALLBACK (open_clicked_cb), video);

报错未声明open_clicked_cb,函数open_clicked_cb是在callbacks.c文件,要在gtk4player.c加上#include “callbacks.h”

单击最上方铁锤图标,编译程序gtk4player

…/src/gtk4player.c:6:6: warning: no previous declaration for ‘activate’ [-Wmissing-declarations]
6 | void activate( GtkApplication *app, gpointer user_data )
报错未声明activate,函数activate是在gtk4player.c文件,要在gtk4player.c加上#include “gtk4player.h”,要加上自身的头文件

单击最上方铁锤图标,编译程序gtk4player

…/src/callbacks.c:4:1: warning: no previous declaration for ‘open_dialog_response_cb’ [-Wmissing-declarations]
5 | open_dialog_response_cb (GObject *source,
报错未声明open_dialog_response_cb,函数open_dialog_response_cb是在callbacks.c文件,要在callbacks.c加上#include “callbacks.h”,要加上自身的头文件

直到最上方铁锤图标左边显示:构建已成功
ruhongvnc@localhost:~/工程/gtk4player/_build/src> pwd
/home/ruhongvnc/工程/gtk4player/_build/src
ruhongvnc@localhost:~/工程/gtk4player/_build/src> ls
gtk4player gtk4player.p
ruhongvnc@localhost:~/工程/gtk4player/_build/src> ./gtk4player
运行一下编译出来的执行文件gtk4player,左上角第二、第三个按钮没有显示图标

二、glib-compile-resources将ui文件、图片纳入到二进制执行文件gtk4player中
ruhongvnc@localhost:~/工程/gtk4player> glib-compile-resources --help
将ui文件、图片打包成gtk4player-resources.c和gtk4player-resources.h,然后与其它c文件一起编译成二进制执行文件gtk4player

修改src文件夹下的meson.build文件,删除注释符号#,恢复关于gtk4player.gresource.xml的4行内容

 gtk4player_sources += gnome.compile_resources('gtk4player-resources',
   'gtk4player.gresource.xml',
   c_name: 'gtk4player'
 )

它原样设置是ui文件与c文件放在一起,gtk4player.gresource.xml与ui文件放在一起的,src文件夹还有一个gtk文件夹放有help-overlay.ui
将gtk文件夹改名为images删除其中的help-overlay.ui文件,将gtk4player需要的picture01.png、picture02.png和you_belong_to_me_taylor_swift.mp4放在images文件夹中
ruhongvnc@localhost:~/工程/gtk4player/src> tree
.
├── callbacks.c
├── callbacks.h
├── gtk4player.c
├── gtk4player.gresource.xml
├── gtk4player.h
├── images
│ ├── picture01.png
│ ├── picture02.png
│ └── you_belong_to_me_taylor_swift.mp4
├── main.c
└── meson.build

将gtk4player.gresource.xml修改成如下:

<?xml version="1.0" encoding="UTF-8"?>
<gresources>
  <gresource prefix="/home/ruhongvnc/工程/gtk4player/src/">
      <file>images/picture01.png</file>
      <file>images/picture02.png</file>
      <file>images/you_belong_to_me_taylor_swift.mp4</file>
  </gresource>
</gresources>

prefix=后面双引号的内容/home/ruhongvnc/工程/gtk4player/src/
<file>images/picture01.jpg</file>,两个<file>之间的内容images/picture01.png
两个内容拼接在一起/home/ruhongvnc/工程/sliding_puzzle/src/images/picture01.jpg刚好就是文件picture01.png的绝对路径
prefix=后面双引号的内容/home/ruhongvnc/工程/sliding_puzzle/src/也正好是sliding_puzzle.gresource.xml所在的路径
命令realpath是专门用来显示文件的绝对路径的
ruhongvnc@localhost:~/工程/gtk4player/src> realpath gtk4player.gresource.xml
/home/ruhongvnc/工程/gtk4player/src/gtk4player.gresource.xml
ruhongvnc@localhost:~/工程/gtk4player/src> realpath images/picture01.png
/home/ruhongvnc/工程/gtk4player/src/images/picture01.png

<file preprocess=“xml-stripblanks”>images/picture01.jpg</file>,这样写法是会报错,只有ui文件才需要preprocess="xml-stripblanks"预处理ui文件去除XML中的空白字符以减小体积

编辑gtk4player.c,将这两行内容
image = gtk_image_new_from_file (“/home/ruhongvnc/工程/video_player_gtk4meson/data/picture01.png”);
image = gtk_image_new_from_file (“/home/ruhongvnc/工程/video_player_gtk4meson/data/picture02.png”);
改成
image = gtk_image_new_from_resource (“/home/ruhongvnc/工程/gtk4player/src/images/picture01.png”);
image = gtk_image_new_from_resource (“/home/ruhongvnc/工程/gtk4player/src/images/picture02.png”);
也是填写picture01.png的绝对路径,file改成resource

编辑callbacks.c,将这行内容
file = g_file_new_for_uri (“file:///home/ruhongvnc/工程/video_player_gtk4meson/data/you_belong_to_me_taylor_swift.mp4”);
改成
file = g_file_new_for_uri (“resource:///home/ruhongvnc/工程/gtk4player/src/images/you_belong_to_me_taylor_swift.mp4”);
也是填写you_belong_to_me_taylor_swift.mp4的绝对路径,file改成resource

单击最上方铁锤图标,编译程序gtk4player,显示:构建已成功
ruhongvnc@localhost:~/工程/gtk4player/_build/src> pwd
/home/ruhongvnc/工程/gtk4player/_build/src
ruhongvnc@localhost:~/工程/gtk4player/_build/src> gresource list gtk4player
/home/ruhongvnc/工程/gtk4player/src/images/picture01.png
/home/ruhongvnc/工程/gtk4player/src/images/picture02.png
/home/ruhongvnc/工程/gtk4player/src/images/you_belong_to_me_taylor_swift.mp4

检查是否带有图片和mp4
ruhongvnc@localhost:~/工程/gtk4player/_build/src> cp gtk4player /home/ruhongvnc
ruhongvnc@localhost:~/工程/gtk4player/_build/src> cd
ruhongvnc@localhost:~> ./gtk4player

注意:其实是不推荐将视频纳入到二进制执行文件gtk4player中,you_belong_to_me_taylor_swift.mp4是8.2MB,只要你运行gtk4player就会占用8.2MB物理内存,不播放视频也会占用8.2MB物理内存

三、制作图标org.example.gtk4player.svg
在网上找一个播放器的图标,使用gimp改为大小128X128
右击tepic300.jpg——打开方式——gimp——打开
图像——缩放图像——单击解锁固定比例——宽度和高度都输入128——缩放
文件——另存为——保存文件夹为/home/ruhongvnc/——名称为gtk4player128x128.jpg——保存——带我到导出对话框——导出

使用inkscape将格式改为svg
右击gtk4player128x128.jpg——打开方式——inkscape——打开——导入jpeg位图图像:OK
文件——另存为——名称为gtk4player128x128.svg——保存

ruhongvnc@localhost:~> cp gtk4player128x128.svg /home/ruhongvnc/工程/gtk4player/data/icons/hicolor/scalable/apps/org.example.gtk4player.svg
改名和替换原来的org.example.gtk4player.svg

四、改写org.example.gtk4player.desktop.in和org.example.gtk4player.metainfo.xml.in
参考/usr/share/metainfo/vlc.appdata.xml和/usr/share/metainfo/org.gnome.Totem.appdata.xml其中的英文与中文内容
完善英语信息/home/ruhongvnc/工程/gtk4player/data/org.example.gtk4player.desktop.in
[Desktop Entry]
Name=gtk4player
GenericName=Media player
Comment=Read, capture, broadcast your multimedia streams
Exec=gtk4player
Icon=org.example.gtk4player.svg
Terminal=false
Type=Application
Categories=GTK;AudioVideo;Player;Recorder;AudioVideo;Video;
StartupNotify=true
Keywords=Player;Capture;DVD;Audio;Video;Server;Broadcast;

在自己的家目录新建名称为gtk4player_infomation.txt的文本文件,保存英文与中文内容,下一步会用上

参考/usr/share/metainfo/vlc.appdata.xml和/usr/share/metainfo/org.gnome.Totem.appdata.xml其中的英文与中文内容
完善英语信息/home/ruhongvnc/工程/gtk4player/data/org.example.gtk4player.metainfo.xml.in
<p>
This is the built-in media playback function gtk_video_new from the GTK4 toolkit, which integrates the GStreamer decoder. It is simple to use. ollowing four functions in your software development: gtk_media_file_new_for_resource; gtk_video_set_file; gtk_media_stream_set_volume; gtk_media_stream_play; you can play videos. If you use GStreamer code, it requires over a dozen lines and demands expertise in control flow, pipelines, and other advanced concepts.
</p>

先用自己的母语中文写一段关于这个软件的描述,复制到百度翻译,得到英文信息,替换两个<p>之间的“No description”

gschema.xml 是 GNOME 桌面环境中用于定义 ‌GSettings‌ 配置架构(Schema)的 XML 文件。它是 GNOME 应用程序和系统组件存储、管理用户偏好设置的核心机制。
避免使用 .gschema.xml.in‌:除非你有特殊的构建需求,否则直接使用 .gschema.xml。现代构建系统(如 Meson/CMake)通常能很好地处理 XML 文件,不需要通过 intltool 进行预处理。

五、使用xgettext制作po文件,将软件中的英文翻译成中文
单击最上方第三个三角图标——选择运行命令——运行命令——选择gtk4player
单击最上方第二个三角图标,运行程序gtk4player
看到左上的Open和中间的Video Player要翻译成中文

在main.c中的以下内容
#include “config.h”
#include <glib/gi18n.h>
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, “UTF-8”);
textdomain (GETTEXT_PACKAGE);

在meson.build中的以下内容
config_h = configuration_data()
config_h.set_quoted(‘PACKAGE_VERSION’, meson.project_version())
config_h.set_quoted(‘GETTEXT_PACKAGE’, ‘gtk4player’)
config_h.set_quoted(‘LOCALEDIR’, get_option(‘prefix’) / get_option(‘localedir’))
configure_file(output: ‘config.h’, configuration: config_h)
add_project_arguments([‘-I’ + meson.project_build_root()], language: ‘c’)

查看config.h的内容
/home/ruhongvnc/工程/gtk4player/_build
ruhongvnc@localhost:~/工程/gtk4player/_build> cat config.h
/*

  • Autogenerated by the Meson build system.
  • Do not edit, your changes will be lost.
    */
    #pragma once
    #define GETTEXT_PACKAGE “gtk4player”
    #define LOCALEDIR “/app/share/locale”
    #define PACKAGE_VERSION “0.1.0”

这些内容都是与翻译软件有关的,
软件的左上角的Open和中间的Video Player是在gtk4player.c

gtk_window_set_title (GTK_WINDOW (window), "Video Player");
button = gtk_button_new_with_mnemonic ("_Open");
使用_( )将英文单词标记,修改成如下
gtk_window_set_title (GTK_WINDOW (window), _("Video Player"));
button = gtk_button_new_with_mnemonic (_("Open"));

将gtk4player.c加入到pot文件列表/home/ruhongvnc/工程/gtk4player/po/POTFILES
ruhongvnc@localhost:~/工程/gtk4player/po> cat POTFILES
data/org.example.gtk4player.desktop.in
data/org.example.gtk4player.metainfo.xml.in
data/org.example.gtk4player.gschema.xml
src/gtk4player.c

根据pot文件列表路径,必须在data文件夹的上一个文件夹内运行xgettext命令制作po文件
ruhongvnc@localhost:~/工程/gtk4player> ls
_build data org.example.gtk4player.json po src
COPYING meson.build org.example.gtk4player.json~ README.md
ruhongvnc@localhost:~/工程/gtk4player> pwd
/home/ruhongvnc/工程/gtk4player
ruhongvnc@localhost:~/工程/gtk4player> xgettext -f /home/ruhongvnc/工程/gtk4player/po/POTFILES --from-code=UTF-8 --keyword=_ --keyword=N_ -d zh_CN -o /home/ruhongvnc/工程/gtk4player/po/zh_CN.po

使用文本编辑器gedit打开/home/ruhongvnc/工程/gtk4player/po/zh_CN.po填写相应的中文信息
#: data/org.example.gtk4player.desktop.in:3
msgid “gtk4player”
msgstr “gtk4媒体播放器”

#: data/org.example.gtk4player.desktop.in:4
msgid “Media player”
msgstr “gtk4媒体播放器”

#: data/org.example.gtk4player.desktop.in:5
msgid “Read, capture, broadcast your multimedia streams”
msgstr “读取、捕获、广播您的多媒体流”

#: data/org.example.gtk4player.desktop.in:11
msgid “Player;Capture;DVD;Audio;Video;Server;Broadcast;”
msgstr “播放器 捕获 DVD 音频 视频 广播”

#: data/org.example.gtk4player.metainfo.xml.in:7
msgid “”
"This is the built-in media playback function gtk_video_new from the GTK4 "
"toolkit, which integrates the GStreamer decoder. It is simple to use. By "
"combining the following four functions in your software development: "
"gtk_media_file_new_for_resource; gtk_video_set_file; "
"gtk_media_stream_set_volume; gtk_media_stream_play; you can play videos. If "
"you use GStreamer code, it requires over a dozen lines and demands expertise "
“in control flow, pipelines, and other advanced concepts.”
msgstr “这是gtk4工具包自带的媒体播放函数gtk_video_new,背后集成gstreamer解码器,使用简单,在编写软件中同时使用gtk_media_file_new_for_resource; gtk_video_set_file; gtk_media_stream_set_volume; gtk_media_stream_play; 这四个就可以播放视频了,如果你使用gstreamer代码,就需要十几行代码,而且还需要你明白控制流、管道等专业知识。”

#: src/gtk4player.c:17
msgid “Video Player”
msgstr “媒体播放器”

#: src/gtk4player.c:28
msgid “Open”
msgstr “打开”

ruhongvnc@localhost:~/工程/gtk4player/po> cp zh_CN.po zh_CN.po.finish
ruhongvnc@localhost:~/工程/gtk4player/po> ls
LINGUAS meson.build POTFILES zh_CN.po zh_CN.po.finish
完成后复制一份并改名为zh_CN.po.finish,再次重制时会用上
ruhongvnc@localhost:~/工程/gtk4player/po> echo zh_CN > LINGUAS
这句话很关键,告诉gnome-builder已经有zh_CN.po文件会自动制作mo文件

单击最上方铁锤图标,编译程序gtk4player

…/src/gtk4player.c:17:50: error: implicit declaration of function ‘_’ [-Werror=implicit-function-declaration]
17 | gtk_window_set_title (GTK_WINDOW (window), _(“Video Player”));

报错不能识别_()标记,上网查找原因是没有加上#include <glib/gi18n.h>,要在gtk4player.c加上#include <glib/gi18n.h>

单击最上方铁锤图标,编译程序gtk4player

…/data/…/po/zh_CN.po: warning: Charset “CHARSET” is not a portable encoding name.
Message conversion to user’s charset might not work.
/usr/bin/msgfmt: present charset “CHARSET” is not a portable encoding name

报错编码名称被设置为CHARSET,将第17行"Content-Type: text/plain; charset=CHARSET\n"改为
“Content-Type: text/plain; charset=UTF-8\n”

单击最上方铁锤图标,编译程序gtk4player,终于没有报错了

单击最上方第一个三角图标——清理
单击最上方第一个三角图标——重新构建
查看是否有产生mo文件
ruhongvnc@localhost:~/工程/gtk4player/_build/po/zh_CN/LC_MESSAGES> realpath gtk4player.mo
/home/ruhongvnc/工程/gtk4player/_build/po/zh_CN/LC_MESSAGES/gtk4player.mo

查看config.h的内容
#define LOCALEDIR “/app/share/locale”
它是安装在"/app/share/locale",我也不知道究竟是在具体什么地方,来到最后一步,将gtk4player安装到本机电脑才能看到是否有翻译成中文的效果

六、将gtk4player安装到本机电脑才能看到是否有翻译成中文的效果
现在发布软件都是dnf、zypper、apt命令全自动安装了,很少需要用户像以前(N年前)要下载源代码包到本机电脑,解压再configure;make;make install;make uninstall,以下就是全在命令行下操作
应用程序——工具——终端
ruhongvnc@localhost:~> cd 工程/gtk4player
ruhongvnc@localhost:~/工程/gtk4player> mkdir build20260610
ruhongvnc@localhost:~/工程/gtk4player> meson setup --reconfigure build20260610/
ruhongvnc@localhost:~/工程/gtk4player> cd build20260610/
ruhongvnc@localhost:~/工程/gtk4player/build20260610> ninja
[10/10] Linking target src/gtk4player
ruhongvnc@localhost:~/工程/gtk4player/build20260610> su
密码: 切换root用户输入root密码
localhost:/home/ruhongvnc/工程/gtk4player/build20260610 # ninja install
[0/1] Installing files.
Installing data/org.example.gtk4player.desktop to /usr/local/share/applications
Installing data/org.example.gtk4player.metainfo.xml to /usr/local/share/metainfo
Installing src/gtk4player to /usr/local/bin
Installing po/zh_CN/LC_MESSAGES/gtk4player.mo to /usr/local/share/locale/zh_CN/LC_MESSAGES
Installing /home/ruhongvnc/工程/gtk4player/data/org.example.gtk4player.gschema.xml to /usr/local/share/glib-2.0/schemas
Installing /home/ruhongvnc/工程/gtk4player/data/icons/hicolor/scalable/apps/org.example.gtk4player.svg to /usr/local/share/icons/hicolor/scalable/apps
Installing /home/ruhongvnc/工程/gtk4player/data/icons/hicolor/symbolic/apps/org.example.gtk4player-symbolic.svg to /usr/local/share/icons/hicolor/symbolic/apps
Running custom install script ‘/usr/bin/glib-compile-schemas /usr/local/share/glib-2.0/schemas’
Running custom install script ‘/usr/bin/gtk4-update-icon-cache -q -t -f /usr/local/share/icons/hicolor’
Running custom install script ‘/usr/bin/update-desktop-database -q /usr/local/share/applications’

gnome不会扫描/usr/local/share/applications文件夹的,将org.example.gtk4player.desktop复制到/usr/share/applications/
localhost:/home/ruhongvnc/工程/gtk4player/build20260610 # cp /usr/local/share/applications/org.example.gtk4player.desktop /usr/share/applications/
应用程序——影音——gtk4媒体播放器——看到左上角的按钮显示打开,中间标题显示媒体播放器
在这里插入图片描述

运行ninja uninstall就可以删除它了
localhost:/home/ruhongvnc/工程/gtk4player/build20260610 # rm /usr/share/applications/org.example.gtk4player.desktop

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐