代码之家  ›  专栏  ›  技术社区  ›  Hanlon

处理命令行参数时不显示GUI

  •  1
  • Hanlon  · 技术社区  · 6 年前

    问题是程序只处理命令行参数并退出,而不显示GUI。

    例如:

    #include <gtk/gtk.h>
    
    static gint print_cmd_arg(GApplication *app, GApplicationCommandLine *app_cmd, int *argc)
    {
        if (*argc > 1)
        {
            char **argv = g_application_command_line_get_arguments(app_cmd, argc);
            GFile *file = g_file_new_for_commandline_arg(argv[1]);
    
            if (g_file_query_exists(file, NULL))
            {
                char *text;
                g_file_load_contents(file, NULL, &text, NULL, NULL, NULL);
                g_print("%s", text);
                g_free(text);
                g_object_unref(file);
                return 0;
            }
            else
            {
                g_print("File \'%s\' does not exist.\n", argv[1]);
                g_object_unref(file);
                return 1;
            }
        }
        return 2;
    }
    
    static void activation(GtkApplication *app, gpointer user_data)
    {
        GtkWidget *window = gtk_application_window_new(app);
        gtk_window_set_default_size(GTK_WINDOW(window), 200, 200);
        gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER_ALWAYS);
        gtk_window_set_title(GTK_WINDOW(window), "Test");
        g_signal_connect(window, "delete-event", G_CALLBACK(gtk_widget_destroy), NULL);
    
        GtkWidget *button = gtk_button_new_with_label("Quit");
        g_signal_connect_swapped(button, "clicked", G_CALLBACK(gtk_widget_destroy), window);
    
        gtk_container_set_border_width(GTK_CONTAINER(window), 10);
        gtk_container_add(GTK_CONTAINER(window), button);
    
        gtk_widget_show_all(window);
    }
    
    int main(int argc, char **argv)
    {
        int status;
        GtkApplication *test = gtk_application_new("this.is.only.a.test", G_APPLICATION_NON_UNIQUE | G_APPLICATION_HANDLES_COMMAND_LINE);
        g_signal_connect(test, "activate", G_CALLBACK(activation), NULL);
        g_signal_connect(G_APPLICATION(test), "command-line", G_CALLBACK(print_cmd_arg), &argc);
        status = g_application_run(G_APPLICATION(test), argc, argv);
        return status;
    }
    

    试着运行这个,你会发现这个程序完全忽略了函数 activation .

    我希望这个程序能同时处理命令行参数和显示GUI。

    而且,我知道我应该用 g_application_command_line_set_exit_status() 在里面 print_cmd_arg 而不是 return 但我不知道该如何做并获取编译器警告。

    1 回复  |  直到 6 年前
        1
  •  1
  •   José Fonte    6 年前

    由于增加了灵活性,在gtkapplication/gapplication上下文中,处理命令行是一个复杂的主题。

    如果您要“重写”命令行处理/解析,那么可以使用各种方法来执行此操作。

    关于这个主题的信息在文档中有些零散。其中一些在这里:

    1. https://wiki.gnome.org/HowDoI/GtkApplication
    2. https://wiki.gnome.org/HowDoI/GtkApplication/CommandLine
    3. https://developer.gnome.org/gio//2.30/GApplication.html#g-application-run
    4. https://developer.gnome.org/gtk3/stable/GtkApplication.html
    5. https://developer.gnome.org/gtk3/stable/gtk-getting-started.html

    1) 你可以阅读:

    处理命令行

    通常,gtkapplication将假定传递给 命令行是要打开的文件。如果没有传递参数,则 它假定正在启动应用程序以显示其主 窗口或空文档。如果提供了文件, 将从打开的信号接收这些文件(以gfile的形式)。 否则,您将收到激活信号。建议 新的应用程序使用此命令行的默认处理 争论。

    如果您想以更高级的方式处理命令行参数, 有几种(互补的)机制可以让您做到这一点。

    重要的一点是:

    特别注意,可以使用动作激活 而不是激活或打开。这是完全合理的 应用程序可以在不发出激活信号的情况下启动。 activate只应该是默认的“无选项启动”信号 . 行动是用来做其他事情的。

    所以,有各种方法来处理参数。问题在于你打算怎么做,做什么。如果参数是文件,则可以使用 open 发出信号,避免处理命令行。

    要解决实际问题,正如您可能得出的结论,activate不会被激发,但您可以使用 g_application_activate 在命令行回调中,例如:

    static gint print_cmd_arg(GApplication *app, GApplicationCommandLine *app_cmd, int *argc)
    {
        /* ADD THIS TO YOUR CODE */
        g_application_activate(app);
        /* ENDS HERE */
    
        if (*argc > 1)
        {
            char **argv = g_application_command_line_get_arguments(app_cmd, argc);
            GFile *file = g_file_new_for_commandline_arg(argv[1]);
    
            if (g_file_query_exists(file, NULL))
            {
                char *text;
                g_file_load_contents(file, NULL, &text, NULL, NULL, NULL);
                g_print("%s", text);
                g_free(text);
                g_object_unref(file);
                return 0;
            }
            else
            {
                g_print("File \'%s\' does not exist.\n", argv[1]);
                g_object_unref(file);
                return 1;
            }
        }
        return 2;
    }