Vala GtkTemplate: ресурс пользовательского интерфейса не найден - PullRequest
2 голосов
/ 02 апреля 2020

Я пытаюсь использовать GtkTemplate, но это действительно раздражает, что не работает. Я определил файловые ресурсы .ui, правильно назвав его и т. Д. c.

Вот мои файлы:

meson.build:

# project name and programming language
project('myproject', 'vala', 'c', version: '1.0.0')

# add resources to the executeable
gnome = import('gnome')
gresources = gnome.compile_resources(
    meson.project_name() + '.resources',
    'data/gresources.xml',
    c_name: 'resources'
)

executable(
    meson.project_name(),

    'src/OpenFileWindow.vala',
    'src/Main.vala',

    gresources,

    dependencies: [
        dependency('gtk+-3.0'),
        dependency('gio-2.0'),
    ],
    install: true
)

src / OpenFileWindow .vala:

using Gtk;

namespace MyProject {

    [GtkTemplate (ui="/ui/OpenFileWindow.ui")]
    public class OpenFileWindow : Window {
        [GtkChild]
        Button btn_browse;

        public OpenFileWindow() {

        }

        [GtkCallback]
        private void btn_browse_clicked(Button btn) {
            stdout.printf("CLICKED");
        }
    }
}

ui / OpenFileWindow.ui:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
  <requires lib="gtk+" version="3.20"/>
  <template class="OpenFileWindow" parent="GtkWindow">
    <property name="can_focus">False</property>
    <child>
      <object class="GtkButton" id="btn_browse">
        <property name="label">gtk-open</property>
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="receives_default">True</property>
        <property name="use_stock">True</property>
        <property name="image_position">top</property>
        <property name="always_show_image">True</property>
        <signal name="clicked" handler="myproject_openfilewindow_btn_browse_clicked" swapped="no"/>
      </object>
    </child>
  </template>
</interface>

data / gresources. xml:

<?xml version="1.0" encoding="UTF-8"?>
<gresources>
  <gresource prefix="/">
    <file preprocess="xml-stripblanks">ui/OpenFileWindow.ui</file>
  </gresource>
</gresources>

И когда я построенный с мезон и ниндзя, он выдает эту ошибку:

valac -C --debug --debug --pkg gio-2.0 --pkg gtk+-3.0 --color=always --directory myproject@exe --basedir ../ --gresources=../data/gresources.xml ../src/OpenFileWindow.vala ../src/Main.vala

../src/OpenFileWindow.vala:6.5-6.40: error: UI resource not found: `/ui/OpenFileWindow.ui'. Please make sure to specify the proper GResources xml files with --gresources and alternative search locations with --gresourcesdir.
    public class OpenFileWindow : Window {

В чем проблема, я действительно не могу видеть это ... Спасибо!

1 Ответ

2 голосов
/ 02 апреля 2020

GResource - файловая система только для чтения для файлов, которые были встроены в скомпилированный двоичный файл. В проекте Vala GUI это можно использовать для хранения изображений, значков и т. Д. c. в двоичном формате.

GtkBuilder Файлы определения пользовательского интерфейса также могут быть встроены, и Vala имеет дополнительную поддержку для этого с атрибутами [GtkTemplate], [GtkChild] и [GtkCallback]. Часть этой поддержки включает проверку типов во время компиляции. Проверка должна получить исходный файл и определить имя файла для файловой системы GResource в памяти, и именно здесь происходит сбой проекта. Любой, кто хочет улучшить это, должен исправить codegen / valagtkmodule.vala в компиляторе Vala. На данный момент, однако, чтобы ваш проект заработал, вам нужно использовать более простую файловую структуру для ресурсов.

Сначала переместите data/gresource.xml в каталог ui/. Затем измените prefix на /ui. Это означает, что файловая система в памяти будет использовать имя, соответствующее атрибуту GtkTemplate, который вы используете в коде Vala. Также удалите ui/ из имени файла, чтобы получить плоскую структуру каталогов:

<?xml version="1.0" encoding="UTF-8"?>
<gresources>
  <gresource prefix="/ui/">
    <file preprocess="xml-stripblanks">OpenFileWindow.ui</file>
  </gresource>
</gresources>

Вам также необходимо изменить определение gresources в файле meson.build:

gresources = gnome.compile_resources(
    meson.project_name() + '.resources',
    'ui/gresources.xml',
    source_dir: ['ui']
)

Используется source_dir для поддержания работы ссылок в плоской структуре каталогов.

Теперь вы больше не должны получать сообщение об ошибке. Взгляните на Geary в качестве примера проекта, в котором используется большое количество файлов пользовательского интерфейса GtkBuilder. В этом проекте файл GResource находится в том же каталоге, что и другие файлы.

Ваш проект по-прежнему не будет компилироваться, поскольку компилятор Vala обнаружил, что для [GtkCallback] нет сигнала. Это проблема разрешения имен, и вам нужно изменить только одну строку в файле OpenFileWindow.ui с:

<signal name="clicked" handler="myproject_openfilewindow_btn_browse_clicked" swapped="no"/>

на

<signal name="clicked" handler="btn_browse_clicked" swapped="no"/>

Обновление

Для Vala компилятор для проверки типов файлов определения пользовательского интерфейса GtkBuilder gresource. xml должен быть только в каталоге общего предка. Это делает возможной структуру каталогов ресурсов:

resources/
├── components/
│   └── zoom-bar.ui
├── icons/
│   └── project.svg
├── layouts/
│   └── main-window.ui
├── themes/
│   ├── dark.css
│   └── light.css
└── filelist.gresource.xml

Файл filelist.gresource.xml требует prefix из /, но подкаталоги копируются из исходных файлов в оперативную память files:

<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/">
<file preprocess="xml-stripblanks" compressed="true">layouts/main-window.ui</file>
<file preprocess="xml-stripblanks" compressed="true">components/zoom-bar.ui</file>
</gresource>
</gresources>

Затем в Vala можно получить к нему доступ:

[GtkTemplate (ui="/layouts/main-window.ui")]

Аргумент source_dir для gnome.compile_resources() в meson.build все еще необходимо установить:

gresources = gnome.compile_resources(
    'project-resources',
    'resources/filelist.gresource.xml',
    source_dir: ['resources']
)
...