GTKmm 3:使用Gtk :: Application解析命令行 [英] GTKmm 3: Parse command line with Gtk::Application

查看:306
本文介绍了GTKmm 3:使用Gtk :: Application解析命令行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用GTK的argv处理,但似乎有一些主循环的问题。



我的目标是解析命令行后GTK删除了它的选项(如 - display ),但在打开一个窗口之前,因为我想让我的应用程序只能使用CLI界面,使用Glib等。这就是为什么我试图打开 command_line 信号处理程序中的窗口。



  #include< gtkmm.h> 
int main(int argc,char ** argv){
auto app = Gtk :: Application :: create(argc,argv,my.app);
Gtk :: ApplicationWindow win;
return app-> run(win);
}

但只需添加 HANDLES_COMMAND_LINE flag破坏:窗口从不显示。

  #include< gtkmm.h> 
int on_cmd(const Glib :: RefPtr< Gio :: ApplicationCommandLine>&){
return 0;
}
int main(int argc,char ** argv){
auto app = Gtk :: Application :: create(argc,argv,my.app,
Gio :: APPLICATION_HANDLES_COMMAND_LINE);
app-> signal_command_line()。connect(sigc :: ptr_fun(on_cmd),false);
Gtk :: ApplicationWindow win;
return app-> run(win);
}

所以我认为 command_line 处理程序没有实际上预计返回?但文档说 run 启动主循环。我没有找到一个方法,只是等待主循环完成,所以我手动曲柄。窗口被再次显示,但是当循环关闭时循环仍然继续,这是该代码最小的问题:

  #include< gtkmm.h> 
int on_cmd(const Glib :: RefPtr< Gio :: ApplicationCommandLine>&
Glib :: RefPtr< Gtk :: Application>& app){
Gtk :: ApplicationWindow win app);
// app-> run(win); --- land here again - >堆栈溢出。
win.show();
//这看起来很错,但似乎工作?
while(true)
Glib :: MainContext :: get_default() - > iteration(true);
//从不到达
return 0;
}
int main(int argc,char ** argv){
auto app = Gtk :: Application :: create(argc,argv,my.app,
Gio :: APPLICATION_HANDLES_COMMAND_LINE);
app-> signal_command_line()。connect(
sigc :: bind(sigc :: ptr_fun(on_cmd),app),false);
return app-> run();
}

(gtkmm-3.0版本3.5.13)

$ b $结果是,关键是在应用程序上调用 activate

HANDLES_COMMAND_LINE 不会自动执行。



我的第二个示例是缺少一个行:

  #include< gtkmm.h> 
int on_cmd(const Glib :: RefPtr< Gio :: ApplicationCommandLine>&
Glib :: RefPtr< Gtk :: Application>& app){
app-> activate ); //< ----
return 0;
}
int main(int argc,char ** argv){
auto app = Gtk :: Application :: create(argc,argv,my.app,
Gio :: APPLICATION_HANDLES_COMMAND_LINE);
app-> signal_command_line()。connect(
sigc :: bind(sigc :: ptr_fun(on_cmd),app),false);
Gtk :: ApplicationWindow win;
return app-> run(win);
}

这是一个子类应用程序,使用Glib解析命令行,如果 - gui 存在,打开一个窗口,并且只在窗口关闭后终止。



使用 gtk_get_option_group 添加了GTK选项(和帮助),因此 - help-all 真的显示所有适用的选项,我们不必须依靠 gtk_main(argc,argv)删除GTK选项,即argments可以推迟到 run(argc,argv) call(但不必如此)如果应用程序构造函数给出参数,它将删除GTK选项,除了 - help-gtk ,我们的处理程序从来没有看到它们,但仍然可以显示它的帮助。)似乎无关紧要)

  #include < gtkmm.h> 
struct MyApp:Gtk :: Application {
MyApp():Gtk :: Application(my.app,
Gio :: APPLICATION_HANDLES_COMMAND_LINE){}
int on_command_line Glib :: RefPtr< Gio :: ApplicationCommandLine>& cmd){
//解析参数:
Glib :: OptionContext ctx;
Glib :: OptionGroup group(options,main options);
bool show_gui = false;
Glib :: OptionEntry entry;
entry.set_long_name(gui);
entry.set_description(show the gui。);
group.add_entry(entry,show_gui);
ctx.add_group(group);
//添加GTK选项,--help-gtk等等
Glib :: OptionGroup gtkgroup(gtk_get_option_group(true));
ctx.add_group(gtkgroup);
int argc;
char ** argv = cmd-> get_arguments(argc);
ctx.parse(argc,argv);
//可能显示gui
if(show_gui)
activate();
return 0;
}
Gtk :: ApplicationWindow * main;
void on_activate(){
//不能使用Gtk :: manage,所以我们必须保留
//引用或主循环退出。
main = new Gtk :: ApplicationWindow();
add_window(* main);
main-> show();
}
};
int main(int argc,char ** argv){
return MyApp()。run(argc,argv);
}


I'm trying to use GTK's argv-handling, but there seem to be some issues with the main loop.

My goal is to parse the command line after GTK removed its options (like --display), but before opening a window, because I want my app to be usable with a CLI-only interface, too, with both variants making use of Glib etc. This is why I'm trying to open the window in the command_line signal handler.

This works as expected, exits when the window is closed.

#include <gtkmm.h>
int main(int argc, char **argv) {
    auto app = Gtk::Application::create(argc, argv, "my.app");
    Gtk::ApplicationWindow win;
    return app->run(win);
}

But simply adding the HANDLES_COMMAND_LINE flag destroys that: The window is never shown.

#include <gtkmm.h>
int on_cmd(const Glib::RefPtr<Gio::ApplicationCommandLine> &) {
    return 0;
}
int main(int argc, char **argv) {
    auto app = Gtk::Application::create(argc, argv, "my.app",
                 Gio::APPLICATION_HANDLES_COMMAND_LINE);
    app->signal_command_line().connect(sigc::ptr_fun(on_cmd), false);
    Gtk::ApplicationWindow win;
    return app->run(win);
}

So I figured that the command_line handler isn't actually suppposed to return? But the documentation says run starts the main loop. I haven't found a method that simply waits for the main loop to finish, so I crank it manually. The window is being shown again, but of course the loop continues once it's closed, which is the least problem with that code:

#include <gtkmm.h>
int on_cmd(const Glib::RefPtr<Gio::ApplicationCommandLine> &,
           Glib::RefPtr<Gtk::Application> &app) {
    Gtk::ApplicationWindow win(app);
    // app->run(win); --- lands here again -> stack overflow.
    win.show();
    // This looks very wrong but seems to work?!
    while(true)
        Glib::MainContext::get_default()->iteration(true);
    // never reach this
    return 0;
}
int main(int argc, char **argv) {
    auto app = Gtk::Application::create(argc, argv, "my.app",
                 Gio::APPLICATION_HANDLES_COMMAND_LINE);
    app->signal_command_line().connect(
      sigc::bind(sigc::ptr_fun(on_cmd), app), false);
    return app->run();
}

(gtkmm-3.0 version 3.5.13)

解决方案

Turns out, the key is calling activate on the application. The default handler which is executed when HANDLES_COMMAND_LINE is not given does that automatically.

My second example was just missing one line:

#include <gtkmm.h>
int on_cmd(const Glib::RefPtr<Gio::ApplicationCommandLine> &,
  Glib::RefPtr<Gtk::Application> &app) {
    app->activate(); // <----
    return 0;
}
int main(int argc, char **argv) {
    auto app = Gtk::Application::create(argc, argv, "my.app",
                 Gio::APPLICATION_HANDLES_COMMAND_LINE);
    app->signal_command_line().connect(
      sigc::bind(sigc::ptr_fun(on_cmd), app), false);
    Gtk::ApplicationWindow win;
    return app->run(win);
}

Here's a subclassed application which parses the command line using Glib, and if --gui is present, opens a window and only terminates after the window is closed.

Using gtk_get_option_group adds the GTK options (and help) to it, so --help-all really shows all applicable options, and we don't have to rely on gtk_main(argc, argv) to remove the GTK options, i.e. the argments can be deferred to the run(argc, argv) call (but don't have to. If the application constructor is given the arguments, it will remove the GTK options, except --help-gtk, our handler just never sees them but can still display help for it. Doesn't seem to matter either way)

#include <gtkmm.h>
struct MyApp : Gtk::Application {
    MyApp() : Gtk::Application("my.app",
      Gio::APPLICATION_HANDLES_COMMAND_LINE) {}
    int on_command_line(const Glib::RefPtr<Gio::ApplicationCommandLine> &cmd) {
        // parse arguments:
        Glib::OptionContext ctx;
        Glib::OptionGroup group("options", "main options");
        bool show_gui = false;
        Glib::OptionEntry entry;
        entry.set_long_name("gui");
        entry.set_description("show the gui.");
        group.add_entry(entry, show_gui);
        ctx.add_group(group);
        // add GTK options, --help-gtk, etc
        Glib::OptionGroup gtkgroup(gtk_get_option_group(true));
        ctx.add_group(gtkgroup);
        int argc;
        char **argv = cmd->get_arguments(argc);
        ctx.parse(argc, argv);
        // maybe show the gui
        if(show_gui)
            activate();
        return 0;
    }
    Gtk::ApplicationWindow *main;
    void on_activate() {
        // can't use Gtk::manage, so we have to keep
        // the reference or the main loop quits.
        main = new Gtk::ApplicationWindow();
        add_window(*main);
        main->show();
    }
};
int main(int argc, char **argv) {
    return MyApp().run(argc, argv);
}

这篇关于GTKmm 3:使用Gtk :: Application解析命令行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆