Как создать средство выбора файлов с помощью GtkAda? - PullRequest
1 голос
/ 10 июля 2019

Я пытаюсь создать приложение с помощью GtkAda, и мне нужно, чтобы пользователь выбрал файл на своем ПК.Однако я не нашел способа создать средство выбора файлов, не приведя к этой ошибке: поднял PROGRAM_ERROR: необработанный сигнал.

Используя Glade 3.22.1

Я попытался создатькнопку выбора файла и связать ее с диалоговым окном выбора файла.Это приводит к той же ошибке.


Без поляны

Я попытался создать диалог выбора файла и кнопку выбора файла в GPS, но та же ошибка.

Затем я нашелпакет Gtkada.File_Selection.В его описании говорится, что он обрабатывает сигналы самостоятельно и нуждается только в одной функции.К сожалению, это приводит к той же роковой ошибке.

Я работаю над Fedora 29. Версия GtkAda 2018, GPS 2018 и GNAT 8.3.1.

Log_Filter_Handlers.ads

with Gtkada.File_Selection;   use Gtkada.File_Selection;

package Log_Filter_Handlers is

   Retour : Unbounded_String;


   procedure Button_Select_File_Clicked
     (Self : access Gtk_Button_Record'Class);

end Log_Filter_Handlers;

Log_Filter_Handlers.adb

   procedure Button_Select_File_Clicked
     (Self : access Gtk_Button_Record'Class) is

   begin

      Retour := To_Unbounded_String
        (File_Selection_Dialog (Title       => "Select your file",
                                Default_Dir => "",
                                Dir_Only    => False,
                                Must_Exist  => True) );

   end Button_Select_File_Clicked;

Gtkada-File_Selection.ads

package Gtkada.File_Selection is

function File_Selection_Dialog

      (Title       : Glib.UTF8_String := "Select File";
      Default_Dir : String := "";
      Dir_Only    : Boolean := False;
      Must_Exist  : Boolean := False) return String;

end Gtkada.File_Selection;

Как только приложение создает виджет выбора файлов (будь то диалогили кнопка), в этом случае вызывая Button_Select_File_Clicked.Это сразу приводит к этой ошибке: raised PROGRAM_ERROR : unhandled signal

У меня тоже есть некоторые предупреждения

Gtk-Message: 10:43:33.615: Failed to load module "pk-gtk-module"

Gtk-Message: 10:43:33.615: Failed to load module "canberra-gtk-module"

Gtk-Message: 10:43:33.616: Failed to load module "pk-gtk-module"

Gtk-Message: 10:43:33.616: Failed to load module "canberra-gtk-module"

Fontconfig warning: "/home/bob/Applications/Gnat_IDE/Gnat-community/etc/fonts/fonts.conf", line 86: unknown element "blank"

(log_filter_main:24417): Gtk-WARNING **: 10:43:33.841: Could not load a pixbuf from icon theme.

This may indicate that pixbuf loaders or the mime database could not be found.

Спасибо.

1 Ответ

2 голосов
/ 10 июля 2019

Трудно сказать, что вызывает необработанную ошибку сигнала.Вы могли бы сделать трассировку стека, чтобы увидеть, где возникает исключение (см. Также пример для код Розетты ).

Пример ниже работает на GNAT CE 2019. Вы можете протестировать его вв вашей собственной среде, чтобы увидеть, сохраняется ли проблема, или протестируйте свой собственный код с последней версией GtkAda, найденной на GitHub .


Обновление

Быстрый поиск показывает, что Program_Error с сообщением "необработанный сигнал" никогда не вызывается из GtkAda.На самом деле, похоже, что такого рода исключения могут возникать только во время выполнения GNAT / Ada (см. init.c и seh_init.c).И хотя seh_init.c используется только средами выполнения, нацеленными на Win32 и Cygwin (см. Комментарии в начале этого файла), init.c используется в различных других средах выполнения, в том числе для Linux.Следовательно, я думаю, что Program_Error, который вы наблюдаете, повышается в init.c, потому что некоторый сигнал kernel не может быть обработан во время выполнения GNAT / Ada.

Вы можете получить некоторые дополнительныеинформация путем отслеживания сигналов, отправляемых в ваше приложение (см. также этот пост на SO):

strace -e 'trace=!all' <program_name>

main.adb

with File_Selection_Demo;

procedure Main is
begin
   File_Selection_Demo.Run;
end Main;

file_selection_demo.ads

package File_Selection_Demo is

   procedure Run;

end File_Selection_Demo;

file_selection_demo.adb

with Ada.Text_IO;

with Gtk.Main;
with Gtk.Widget;
with Gtk.Builder;
with Gtk.Window;
with Gtk.Button;
with Gtk.GEntry;

with Gtkada.File_Selection;

with Glib;       use Glib;
with Glib.Error; use Glib.Error;

package body File_Selection_Demo is

   --  Widgets
   Builder : Gtk.Builder.Gtk_Builder;
   Window  : Gtk.Window.Gtk_Window;
   Button  : Gtk.Button.Gtk_Button;
   GEntry  : Gtk.GEntry.Gtk_Entry;


   procedure Destroy_Event_Callback
     (Widget : access Gtk.Widget.Gtk_Widget_Record'Class);

   procedure Clicked_Event_Callback
     (Button : access Gtk.Button.Gtk_Button_Record'Class);


   ---------
   -- Run --
   ---------

   procedure Run is

      use Gtk.Builder;
      use Gtk.Window;
      use Gtk.Button;
      use Gtk.GEntry;

      Success : GUint;
      Error   : aliased GError;

   begin

      --  Initialize GtkAda.
      Gtk.Main.Init;

      -- Construct a Gtk_Builder instance and load our UI description.
      Gtk_New (Builder);

      Success := Builder.Add_From_File ("./example.glade", Error'Access);
      if Success = 0 then
         Ada.Text_IO.Put_Line ("failed to read Glade file");
         Error_Free (Error);         
         return;
      end if;

      --  Entry
      GEntry := Gtk_Entry (Builder.Get_Object ("Entry"));

      --  Button
      Button := Gtk_Button (Builder.Get_Object ("Button"));
      Button.On_Clicked (Clicked_Event_Callback'Access);

      -- Window
      Window := Gtk_Window (Builder.Get_Object ("Window"));
      Window.On_Destroy (Destroy_Event_Callback'Access);
      Window.Show_All;

      -- Start the main event loop
      Gtk.Main.Main;

   end Run;


   ----------------------------
   -- Destroy_Event_Callback --
   ----------------------------

   procedure Destroy_Event_Callback
     (Widget : access Gtk.Widget.Gtk_Widget_Record'Class)
   is
   begin
      Gtk.Main.Main_Quit;
   end Destroy_Event_Callback;

   ----------------------------
   -- Clicked_Event_Callback --
   ----------------------------

   procedure Clicked_Event_Callback
     (Button : access Gtk.Button.Gtk_Button_Record'Class) is
   begin

      declare
         Response : String :=
                      Gtkada.File_Selection.File_Selection_Dialog
                        (Title       => "Select your file",
                         Default_Dir => "",
                         Dir_Only    => False,
                         Must_Exist  => True);
      begin
         GEntry.Set_Text (Response);
      end;

   end Clicked_Event_Callback;

end File_Selection_Demo;

example.glade

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.1 -->
<interface>
  <requires lib="gtk+" version="3.10"/>
  <object class="GtkWindow" id="Window">
    <property name="can_focus">False</property>
    <property name="title" translatable="yes">GTK File Selector Demo</property>
    <property name="resizable">False</property>
    <property name="window_position">center</property>
    <child>
      <object class="GtkBox" id="HBox">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <child>
          <object class="GtkEntry" id="Entry">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="margin_left">10</property>
            <property name="margin_right">10</property>
            <property name="margin_top">5</property>
            <property name="margin_bottom">5</property>
            <property name="hexpand">True</property>
            <property name="editable">False</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkButton" id="Button">
            <property name="label" translatable="yes">Choose File...</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
            <property name="margin_left">10</property>
            <property name="margin_right">12</property>
            <property name="margin_top">5</property>
            <property name="margin_bottom">5</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>
...