当我的Gtk3窗口*已经*关闭时,我可以挂接什么事件?
我希望在Gtk3窗口关闭后执行一些代码。我尝试了当我的Gtk3窗口*已经*关闭时,我可以挂接什么事件?,gtk,gdk,Gtk,Gdk,我希望在Gtk3窗口关闭后执行一些代码。我尝试了delete event,destroy,以及destroy event,但似乎根本没有触发 我知道Gdk和Gtk之间有一些区别,但我不确定这到底是什么。我想我问的是对的 我正在使用gtk\u window\u new()的node.js绑定创建窗口,并使用gtk\u window\u close()关闭它。当执行此操作并使用上述事件时,事件处理程序会在窗口仍在屏幕上时启动 编辑: 根据要求,一些示例代码: const gi = require('
delete event
,destroy
,以及destroy event
,但似乎根本没有触发
我知道Gdk和Gtk之间有一些区别,但我不确定这到底是什么。我想我问的是对的
我正在使用gtk\u window\u new()
的node.js绑定创建窗口,并使用gtk\u window\u close()
关闭它。当执行此操作并使用上述事件时,事件处理程序会在窗口仍在屏幕上时启动
编辑:
根据要求,一些示例代码:
const gi = require('node-gtk')
const Gtk = gi.require('Gtk', '3.0');
gi.startLoop();
Gtk.init();
const win = new Gtk.Window();
win.on('destroy', () => Gtk.mainQuit());
win.on('delete-event', () => false);
const button = new Gtk.Button({ label: 'Do it' });
win.add(button);
button.on('clicked', function () {win.close();});
win.showAll();
Gtk.main();
shell_command("wmctrl -lG");
function shell_command(cmd_str) {
const execSync = require('child_process').execSync;
code = execSync(cmd_str);
return code.toString();
}
在我的LinuxMint19.3系统上,上面的代码创建了一个带有1个按钮的小窗口。单击按钮会导致执行崩溃,并出现以下终端错误:
Error: Command failed: wmctrl -lG
X Error of failed request: BadWindow (invalid Window parameter)
Major opcode of failed request: 20 (X_GetProperty)
Resource id in failed request: 0x6c00003
Serial number of failed request: 26
Current serial number in output stream: 26
窗口id0x6c00003
是由上述代码创建的窗口的窗口id,运行脚本后但按下按钮前运行wmctrl可以证明这一点
如果我简单地将对wmctrl
的调用放在一个50毫秒的计时器中,它就会正常工作
setTimeout(function () {shell_command("wmctrl -lG");}, 50);
这让我相信这是一种比赛状态。我认为wmctrl
在我的窗口仍然存在时获取窗口ID,但在我的窗口关闭后进一步查询这些ID,从而导致上述错误。这是我的理论,如果它是正确的,Gtk.main()
在窗口真正消失之前返回(提到的其他事件也是如此)。\include
gboolean销毁(gpointer窗口、gpointer测试);
无效破坏1(GtkWidget*窗口,gpointer测试);
int main(int argc,char*argv[]){
GtkWidget*窗口;
gtk_init(&argc,&argv);
窗口=gtk_窗口_新建(gtk_窗口_顶层);
gtk_小部件_添加_事件(gtk_小部件(窗口)、GDK_所有_事件_掩码);
gtk_widget_show(窗口);
g_信号连接(窗口,“销毁”,g_回调(销毁1),空);
g_信号连接(窗口,“销毁事件”,g_回调(销毁),空);
gtk_main();
printf(“关闭应用程序”);
//您可以尝试在此处添加代码
//只有在窗口被破坏后才会退出
睡眠(10);
返回0;
}
无效销毁1(GtkWidget*窗口,gpointer测试){
printf(“睡眠5秒\n”);
gtk_小部件_销毁(gtk_小部件(窗口));
睡眠(5);
gtk_main_quit();
printf(“我睡过觉”\n);
}
gboolean销毁(gpointer窗口、gpointer测试){
printf(“睡眠5秒\n”);
睡眠(5);
printf(“我睡过觉”\n);
返回TRUE;
}
当窗口被完全破坏后,主循环将结束。因此,您可以尝试在gtk_main()之后添加代码
当gdk窗口被破坏时,会发出::destroy事件信号。您很少会收到这种信号,因为大多数小部件在销毁窗口之前都会断开自己与窗口的连接,所以在销毁时没有任何小部件拥有窗口。
()。通常,这些信号删除事件、销毁和销毁事件工作。你能和我们分享一个示例代码吗?也许我们可以理解为什么它不工作。不是它们根本不工作,而是它们工作时窗口仍然在屏幕上<代码>销毁事件似乎实际上不起作用,但这可能与需要在创建时启用它有关,我还没有这样做,也不知道怎么做。共享代码很难,因为这是更广泛应用程序的一部分,而且因为我使用的是大多数人都不熟悉的节点模块。但是,我将尝试在中编辑一些。@SivaGuru代码已添加。在获得销毁信号后,请尝试调用一个函数,该函数释放对主窗口的所有引用(gtk_widget_destroy或g_object_unref or),然后尝试调用gtk.mainQuit()。我试着修改c代码,但它在那里工作。你称之为reace条件的理由似乎是正确的(这个问题也可能与节点gtk有关)。我真不敢相信我是个白痴。显然,把它放在
main()
之后才是应该做的事情。结果证明这并没有起到作用。相反,它导致了wmctrl
中出现的竞争条件。本质上,发生的是Gtk.main()
在win.close()
之后返回,然后我的代码调用wmctrl
,在Gtk实际关闭窗口时运行,这会导致wmctrl
抛出错误Gtk.main()
没有同步结束。我不理解这个问题。你可以像任何示例工作代码一样用wmctrl更新代码吗..我在原始帖子中进一步更新了代码并扩展了解释。我已经改变了我的应用程序,使它不再重要,但未来的搜索可能会关心。
#include <gtk/gtk.h>
gboolean destroy(gpointer window, gpointer testing);
void destroy1(GtkWidget *window, gpointer testing);
int main(int argc, char *argv[]) {
GtkWidget *window;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_add_events(GTK_WIDGET(window), GDK_ALL_EVENTS_MASK);
gtk_widget_show(window);
g_signal_connect(window, "destroy", G_CALLBACK(destroy1), NULL);
g_signal_connect(window, "destroy-event", G_CALLBACK(destroy), NULL);
gtk_main();
printf("closing application \n");
// you could try to add the code here
//which will be only be exited after the window is destroyed
sleep(10);
return 0;
}
void destroy1(GtkWidget *window, gpointer testing) {
printf("sleeping for 5 seconds \n");
gtk_widget_destroy(GTK_WIDGET(window));
sleep(5);
gtk_main_quit();
printf("i have slept \n");
}
gboolean destroy(gpointer window, gpointer testing) {
printf("sleeping for 5 seconds \n");
sleep(5);
printf("i have slept \n");
return TRUE;
}