我如何加上一句;“保存”;gtk文件选择器对话框的按钮?

我如何加上一句;“保存”;gtk文件选择器对话框的按钮?,gtk,gjs,Gtk,Gjs,我有一个Gjs应用程序,需要保存文件。我可以从菜单中打开文件选择器对话框,我添加了“保存”和“取消”按钮,但我无法让“保存”按钮触发任何内容 我知道我应该给它一个回复id,但我不知道那应该是什么样子,也不知道以后我该怎么处理它。 我在这里读到了这一部分: 我可以捕获res并在关闭对话框时触发相关的小日志操作,但“保存”和“取消”按钮都只是关闭对话框,而不做任何事情或说任何话 我的问题是,在GJS中,GTK_RESPONSE_ACCEPT和GTK_RESPONSE_CANCEL应该是什么(看起来

我有一个Gjs应用程序,需要保存文件。我可以从菜单中打开文件选择器对话框,我添加了“保存”和“取消”按钮,但我无法让“保存”按钮触发任何内容

我知道我应该给它一个回复id,但我不知道那应该是什么样子,也不知道以后我该怎么处理它。 我在这里读到了这一部分:

我可以捕获
res
并在关闭对话框时触发相关的小日志操作,但“保存”和“取消”按钮都只是关闭对话框,而不做任何事情或说任何话


我的问题是,在GJS中,GTK_RESPONSE_ACCEPT和GTK_RESPONSE_CANCEL应该是什么(看起来像),我应该如何使用它们?

在GJS枚举中,如
GTK_RESPONSE.*
是数字,实际上是这样的:

//假设这是Gtk导入
常数Gtk={
响应类型:{
无:-1,
拒绝:-2,
接受:-3,
删除事件:-4,
...
}
};
//像这样进入
让响应_id=-3;
if(response_id==Gtk.ResponseType.ACCEPT){
日志(真);
}
还有更多的信息

let saver=new Gtk.filechooser对话框({
标题:“选择目的地”,
//这里的枚举用法是正确的
操作:Gtk.FileChooserAction.SAVE
});
//实际上,响应代码并不重要,因为您
//决定如何处理它。您可以传递数字文本
//比如1,2或者3。可能这不起作用,因为你是
//将字符串作为响应id传递。
saver.add_按钮('Cancel',Gtk.ResponseType.Cancel);
saver.add_按钮('Save',Gtk.ResponseType.OK);
//run()很方便,但请注意,它将阻止当前(仅限)
//线程,直到它返回,所以我通常更喜欢连接到
//GtkDialog::响应信号并使用GtkWidget.show()
saver.connect('response',(对话框,response\u id)=>{
if(response_id==Gtk.ResponseType.OK){
//产出“-5”
打印(应答号);
//注意:我们在调用中使用@dialog而不是“saver”
//避免可能阻止对话框的循环引用
//从被垃圾收集。
让filename=dialog.get_filename();
这里是文件名的地方,你可以考虑。
//把这整件事包装成一个可重复使用的承诺。然后你可以打电话给我
//'resolve(filename)`或'resolve(null)`如果响应是
//不是Gtk.ResponseType.OK。然后您可以“等待”结果
//与run()功能相同,但允许在运行时执行其他代码
//您等待用户。
打印(文件名);
//还要注意,实际上你必须自己写,比如
//使用GFile.GtkFileChooserDialog实际上只是为了获得
//来自用户的文件路径
让file=Gio.file.new_作为_路径(文件名);
file.replace\u contents\u bytes\u async(
//当然,您实际上需要字节来写入,因为间隙
//无法返回值,除非传递所有
//通过数据作为参数,它可能不是最佳选项
新的GLib.Bytes('要写入磁盘的文件内容'),
无效的
假,,
Gio.FileCreateFlags.REPLACE_目的地,
无效的
//使用相同名称的“阴影”变量是另一种方法
//防止回调中的循环引用。
(文件,res)=>{
试一试{
文件。替换内容完成(res);
}捕获(e){
对数误差(e);
}
}
);
}
//完成后,无论响应如何,都要销毁对话框。
dialog.destroy();
});
//为了获得额外的积分,下面是如何实现一个简单的预览小部件;)
saver.preview_widget=new Gtk.Image();
saver.preview\u widget\u active=false;
this.connect('update-preview',(对话框)=>{
试一试{
//您必须导入GdkPixbuf才能使用此工具
让pixbuf=GdkPixbuf.pixbuf.new_从_文件中以_大小(
对话框。获取\u预览\u文件名(),
对话框。获取比例系数()*128,
-1
);
dialog.preview_widget.pixbuf=pixbuf;
dialog.preview_widget.visible=true;
dialog.preview\u widget\u active=true;
//如果出现某种错误或文件不是图像
//我们将隐藏预览小部件
}捕获(e){
dialog.preview_widget.visible=false;
dialog.preview\u widget\u active=false;
}
});
//这就是我们向用户显示对话框的方式
saver.show();

是的,起初我试图传递字符串。。。我终于想到,我需要某种类型的数字,因为文档上说“gint32 response_id Required(NOTNULL)”,我注意到任何数字都可以,但这似乎仍然不是一个好方法。。。谢谢你的帮助@andy.holmes
let actionSaveAs = new Gio.SimpleAction ({ name: 'saveAs' });
    actionSaveAs.connect('activate', () => {
            const saver = new Gtk.FileChooserDialog({title:'Select a destination'});
            saver.set_action(Gtk.FileChooserAction.SAVE);
            saver.add_button('save', 'GTK_RESPONSE_ACCEPT');
            saver.add_button('cancel', 'GTK_RESPONSE_CANCEL');
            const res = saver.run();
            if (res) {
              print(res);
              const filename = saver.get_filename();
              print(filename);
            }
            saver.destroy();
          });
    APP.add_action(actionSaveAs);