如何在Gtk3::FileChooserButton中以编程方式更改文件夹?

huangapple go评论78阅读模式
英文:

How to change the folder in Gtk3::FileChooserButton programmatically?

问题

我正在尝试修复一个Perl GTK3应用程序中的错误。在设置对话框中,有一个FileChooserButton,用于设置文件保存的路径。该应用程序还具有将所有设置保存在配置文件(.xml文件)中,然后在需要时加载这些配置文件的功能。

保存位置存在于三个变量中:

  1. FileChooserButton对象(称为$saveDir_button),可以通过$saveDir_button->get_filename()访问。
  2. 从.xml文件读取的配置文件的.xml对象(称为$settings_xml->{'general'}->{'folder'}
  3. 当前设置值(称为$settings{'general'}->{'folder'}

当用户单击FileChooserButton时,$saveDir_button中的路径会更新。

当用户将设置保存到配置文件时,当前设置$settings{'general'}->{'folder'}以及配置文件的.xml $settingsfile都会更新(然后读入$settings_xml对象):

$settings{'general'}->{'folder'} = Glib::filename_to_unicode($saveDir_button->get_filename());

eval {
    my ($tmpfh, $tmpfilename) = tempfile(UNLINK => 1);
    XMLout(\%settings, OutputFile => $tmpfilename);

    # 最后将文件移动
    mv($tmpfilename, $settingsfile);
};

在加载配置文件时,该值从.xml文件加载到$settings_xml对象,然后写入按钮对象$saveDir_button

$settings_xml = XMLin(IO::File->new($settingsfile));
utf8::decode $settings_xml->{'general'}->{'folder'};
$saveDir_button->set_current_folder($settings_xml->{'general'}->{'folder'});

因此,相关部分是,正确的值现在位于按钮对象中。保存文件时,路径从那里读取。但是,由于某种原因,set_current_folder调用未正确执行。在加载配置文件时,按钮不会更改其值。据我理解,只有用户点击按钮并在文件选择对话框中选择文件夹时,才能更改该值。但是,我需要在加载配置文件时以编程方式设置该值。这是否可行?

我考虑在$settings{'general'}->{'folder'}中写入该值,然后在实际保存文件时从那里读取它。但这有两个缺点:

首先,在加载配置文件后,设置对话框中显示的值仍然是错误的。其次,在代码中需要更改许多地方的保存过程,我有点担心会搞砸事情(我正在学习Perl,我们谈论的是超过10,000行的代码,目前只做了一些小改动)。

英文:

I am trying to fix a bug in a Perl GTK3 app. In the settings dialog there is a FileChooserButton which is being used to set the path where files will be saved. The app also has the ability to save all settings in profiles (.xml files) and then load these profiles when necessary.

The saving location is present in three variables:

  1. The FileChooserButton object (it is called $saveDir_button) and can be accessed via $saveDir_button->get_filename().
  2. The profile's .xml object which is read from an .xml file (it is called $settings_xml->{'general'}->{'folder'})
  3. The current settings value (it is called $settings{'general'}->{'folder'})

When the user clicks the FileChooserButton, the path in $saveDir_button is updated.

When the user saves the settings to a profile, the current settings $settings{'general'}->{'folder'} and also the profile's .xml $settingsfile is updated (which is then read into the $settings_xml object):

		$settings{'general'}->{'folder'}   = Glib::filename_to_unicode($saveDir_button->get_filename());


		eval {
			my ($tmpfh, $tmpfilename) = tempfile(UNLINK => 1);
			XMLout(\%settings, OutputFile => $tmpfilename);

			#and finally move the file
			mv($tmpfilename, $settingsfile);
		};

When the profile is being loaded, the value is loaded from the .xml file into the $settings_xml object and then written into the button object $saveDir_button:

				$settings_xml = XMLin(IO::File->new($settingsfile));
				utf8::decode $settings_xml->{'general'}->{'folder'};
				$saveDir_button->set_current_folder($settings_xml->{'general'}->{'folder'});

So, the relevant part is, that the correct value is now in the button object. When saving files, the path is read from there. But, for some reason, the set_current_folder call isn't executed properly. When loading a profile, the button doesn't change its value. As far as I understand, the value can only be changed by the user, when he clicks the button and selects the folder in the file chooser dialog. But I'd need to set the value programmatically when loading a profile. Is this possible?

I was thinking about writing the value into $settings{'general'}->{'folder'} and then reading it from there when actually saving files. But this has two drawbacks:

Firstly, the shown value in the settings dialog is then still wrong after loading a profile. Secondly, I'd need to change the saving procedure on many places in the code and I'm a bit scared to mess up stuff (I'm just learning Perl and we are speaking about >10k lines of code, I'm currently only making small changes).

答案1

得分: 3

但由于某种原因,“set_current_folder”调用未正确执行。在加载配置文件时,按钮不会更改其值。根据我理解,只有用户在单击按钮并在文件选择对话框中选择文件夹时,才能更改该值。但在加载配置文件时,我需要以编程方式设置该值。这是否可能?

以下是您可以使用set_filename()方法更改按钮值的示例(请注意,对于此示例,只有在文件系统中存在该文件时,按钮才会更改其值):

use v5.36;  # strict + warnings + say
use Gtk3 -init;

my $window = Gtk3::Window->new('toplevel');
$window->signal_connect(destroy  => sub { Gtk3->main_quit() } );
my $grid = Gtk3::Grid->new();
$window->add($grid);
my $button1 = Gtk3::Button->new();
$button1->set_label('Change file chooser label');
my $file_chooser;
$button1->signal_connect('clicked' => sub {
    $file_chooser->set_filename('/etc/anacrontab');
} );
$grid->attach($button1, 0,0,1,1);
my $file_chooser_action = 'open';
$file_chooser = Gtk3::FileChooserButton->new("Open file", $file_chooser_action);
$file_chooser->set_current_folder("/etc");
$grid->attach($file_chooser, 0, 1, 1, 1);
$window->set_default_size(200, 200);
$window->set_position('center_always');
$window->show_all();
Gtk3->main();

如果单击最上面的按钮“Change file chooser label”,底部的文件选择按钮应更改其名称为anacrontab(如果您的文件系统中存在文件/etc/anacrontab)。

英文:

> But, for some reason, the set_current_folder call isn't executed properly. When loading a profile, the button doesn't change its value. When loading a profile, the button doesn't change its value. As far as I understand, the value can only be changed by the user, when he clicks the button and selects the folder in the file chooser dialog. But I'd need to set the value programmatically when loading a profile. Is this possible?

Here is an example of how you can use set_filename() method to change the buttons value (note that for this example, the button will only change its value if the file exists in the file system):

use v5.36;  # strict + warnings + say
use Gtk3 -init;

my $window = Gtk3::Window->new( 'toplevel' );
$window->signal_connect( destroy  => sub { Gtk3->main_quit() } );
my $grid = Gtk3::Grid->new();
$window->add( $grid );
my $button1 = Gtk3::Button->new();
$button1->set_label('Change file chooser label');
my $file_chooser;
$button1->signal_connect('clicked' => sub {
    $file_chooser->set_filename('/etc/anacrontab');
} );
$grid->attach($button1, 0,0,1,1);
my $file_chooser_action = 'open';
$file_chooser = Gtk3::FileChooserButton->new("Open file", $file_chooser_action);
$file_chooser->set_current_folder("/etc");
$grid->attach($file_chooser, 0, 1, 1, 1);
$window->set_default_size( 200, 200 );
$window->set_position('center_always');
$window->show_all();
Gtk3->main();

If you click the topmost button "Change file chooser label", the bottom file chooser button should change its name to anacrontab (if that file /etc/anacrontab exists in you filesystem).

huangapple
  • 本文由 发表于 2023年8月4日 01:23:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76830330.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定