如果正在运行的程序的pid有效,我正在尝试显示一个消息对话框,这是我的基本代码:
Gtk::Main kit (argc, argv);
Glib::RefPtr<Gtk::Builder> refBuilder = Gtk::Builder::create();
try { refBuilder->add_from_file (UI_PATH); }
catch (const Glib::FileError& ex) {
std::cout << "FileError: " << ex.what() << std::endl;
return 1;
}
catch (const Gtk::BuilderError& ex) {
std::cout << "BuilderError: " << ex.what() << std::endl;
return 1;
}
FormUI * ui = 0;
refBuilder->get_widget_derived ("window1", ui);
if (ui) {
kit.run (*ui);
}
delete ui;
构造
signal_delete_event ().connect (sigc::mem_fun (*this, &FormUI::on_delete_event));
方法:
bool FormUI::on_delete_event (GdkEventAny* event) {
if (_pid) {
bool retState;
Gtk::MessageDialog md(*this, Glib::ustring::compose ("<b>%1</b>", _("Warning: youtube-dl in process")), true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true);
md.set_title (PACKAGE_STRING);
md.set_secondary_text (_("Closing can generate a corrupted file, do you want to continue anyway?"));
if (md.run() == Gtk::RESPONSE_YES) {
kill (_pid, 0);
retState = false;
} else {
retState = true;
}
md.hide ();
return retState;
}
return false;
}
有了上述内容,如果pid有效,它会按预期显示messagedialog,但是如果我点击“是”(退出应用程序),它会显示另一个messagedialog ..为什么?
答案 0 :(得分:2)
您说FormUI
来自Gtk::Window
。 Gtk::Window
已a virtual method on_delete_event()
自动连接到delete-event
信号,无问题。哎呀,你实现了一个虚拟的方法而不知道它!所以你通过调用
signal_delete_event ().connect (sigc::mem_fun (*this, &FormUI::on_delete_event));
在不知不觉中将该信号连接两次,并且因为Gtk::Window::on_delete_event()
是虚拟的,所以两个连接都转到您自己的方法。
好的,为什么我们仍然会得到两个对话框?不返回false
意味着关闭窗口?不是真的。
delete-event
是GDK事件。 GDK事件总是返回一个布尔值:如果值为false
(GDK_EVENT_PROPAGATE
),则运行信号连接链中的下一个信号处理程序,如果返回值为true
({ {1}}),信号连接链中没有其他信号运行。
恰巧如果你没有阻止GDK_EVENT_STOP
传播通过信号连接链,窗口就会被破坏。因此,当只连接一个处理程序时,从该处理程序返回delete-event
将有效地销毁窗口。
但现在你连接了两个处理程序。第一个将返回false
,这将导致第二个运行,然后您将获得第二个消息对话框。当那个人返回false
时,你的窗户就会被摧毁。
希望这可以解释这个问题。您可以通过不调用false
或将方法名称更改为其他内容来解决此问题。请务必观看gtkmm文档,以确保您不会意外使用自动连接到信号的其他虚拟方法(我不确定为什么gtkmm提供这些虚拟方法;方便吗?)。并且一定要了解GDK活动的工作原理;如果您真的使用GDK事件(例如处理signal_delete_event().connect()
中的输入),您将需要知道这一点。