Форум русскоязычного сообщества Ubuntu


Хотите сделать посильный вклад в развитие Ubuntu и русскоязычного сообщества?
Помогите нам с документацией!

Автор Тема: обработчики событий в Vala  (Прочитано 1614 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн S9

  • Автор темы
  • Участник
  • *
  • Сообщений: 163
  • Волшебник
    • Просмотр профиля
обработчики событий в Vala
« : 11 Ноября 2014, 14:39:50 »
Всем добра! Пишу одну прогу на Vala, и возник такой вопрос. Как вынести все обработчики событий в отдельный файл?

набросал простую прогу, чтобы подробнее объяснить, что я хочу сделать.
есть класс, который создаёт GUI (GUI.vala)
Код: (vala) [Выделить]
using Gtk;

namespace GUI
{
  public class GUI_Appl : Window
  {
    private Button button;
    private Label label;

    public GUI_Appl ()
    {
        this.title = "Sample";
        this.window_position = WindowPosition.CENTER;
        this.destroy.connect(Gtk.main_quit);
        this.set_resizable(false);
       
        var grid = new Grid();
       
        button = new Button.with_label("Кнопка");
        grid.attach(button, 0, 0, 1, 1);
       
        label = new Label.with_mnemonic("Это строка");
        grid.attach(label, 1, 0, 1, 1);
       
        this.add(grid);
    }
  }
}

есть "главный файл" (Sample.vala) с методом main()
Код: (vala) [Выделить]
using GUI;

public static int main (string[] args)
{
  Gtk.init (ref args);

  var window = new GUI_Appl();
  window.show_all();

  Gtk.main();
 
  return 0;
}

при такой связке, всё собирается и запускается.
valac --pkg gtk+-3.0 GUI.vala Sample.vala --output sampleНо у меня ещё есть файл с обработчиками событий (Signals.vala)
его кидаю к остальным (чуть меняя их) и выходит вот так..
kirra@desktop:~/Документы/Doc/DDS/Sample$ valac --pkg gtk+-3.0 GUI.vala Sample.vala Signals.vala --output sample
Signals.vala:7.5-7.22: error: Access to private member `GUI.GUI_Appl.label' denied
    GUI.GUI_Appl.label.set_text("Я новая строка");
    ^^^^^^^^^^^^^^^^^^
GUI.vala:23.32-23.50: error: invocation of void method not allowed as expression
        button.clicked.connect(Signals.my_signal());
                               ^^^^^^^^^^^^^^^^^^^
Compilation failed: 2 error(s), 0 warning(s)
kirra@desktop:~/Документы/Doc/DDS/Sample$


файлы выглядят так
(Нажмите, чтобы показать/скрыть)

(Нажмите, чтобы показать/скрыть)

(Нажмите, чтобы показать/скрыть)

вопросы такие: почему "Access to private member `GUI.GUI_Appl.label' denied", ведь я указываю геттеры и сеттеры для label?
и почему "invocation of void method not allowed as expression", получается, что метод, передаваемый в обработчику не может быть void?

В итоге, что хочу получить, чтобы кнопка обрабатывала нажатие мемтодом my_signal() из Signal.vala

P.S. сейчас читаю про сигналы, возможно тут надо было применить именно их. Если кому не сложно, то покажите как на моём примере применить сигнал:)

Пользователь решил продолжить мысль 11 Ноября 2014, 14:43:15:
Вот и этот маленький проект
« Последнее редактирование: 11 Ноября 2014, 14:43:16 от S9 »
Burning on the flame
Played the waiting game

Оффлайн alsoijw

  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Re: обработчики событий в Vala
« Ответ #1 : 11 Ноября 2014, 14:52:25 »
Код: (vala) [Выделить]
button.clicked.connect(Signals.my_signal());Заменить на
Код: (vala) [Выделить]
button.clicked.connect(Signals.my_signal);
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн S9

  • Автор темы
  • Участник
  • *
  • Сообщений: 163
  • Волшебник
    • Просмотр профиля
Re: обработчики событий в Vala
« Ответ #2 : 11 Ноября 2014, 15:01:08 »
alsoijw, спасибо огромное:)
Осталось решить только это
kirra@desktop:~/Документы/Doc/DDS/Sample$ valac --pkg gtk+-3.0 GUI.vala Sample.vala Signals.vala --output sample
Signals.vala:7.5-7.22: error: Access to private member `GUI.GUI_Appl.label' denied
    GUI.GUI_Appl.label.set_text("Я новая строка");
    ^^^^^^^^^^^^^^^^^^
Compilation failed: 1 error(s), 0 warning(s)
kirra@desktop:~/Документы/Doc/DDS/Sample$
Burning on the flame
Played the waiting game

Оффлайн alsoijw

  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Re: обработчики событий в Vala
« Ответ #3 : 11 Ноября 2014, 15:04:53 »
S9, английский знаем?
Меняем
Код: (vala) [Выделить]
private Label label { get; set; }На
Код: (vala) [Выделить]
public Label labelОбъявлять метку как свойство излишне.
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн S9

  • Автор темы
  • Участник
  • *
  • Сообщений: 163
  • Волшебник
    • Просмотр профиля
Re: обработчики событий в Vala
« Ответ #4 : 11 Ноября 2014, 15:16:29 »
S9, английский знаем?
Меняем
Код: (vala) [Выделить]
private Label label { get; set; }На
Код: (vala) [Выделить]
public Label labelОбъявлять метку как свойство излишне.
с английским более-менее, но это я уже проверял:)

Пользователь решил продолжить мысль [time]11 Ноябрь 2014, 16:19:41[/time]:
извиняюсь, тупанул, объявив Label в конструкторе. Объявив в namespace всё норм заработало:)
если кому понадобится, то вот весь код

GUI.vala
Код: (vala) [Выделить]
using Gtk;
using Signals;

namespace GUI
{
  public Label label;
  public class GUI_Appl : Window
  {
    private Button button;

    public GUI_Appl ()
    {
        this.title = "Sample";
        this.window_position = WindowPosition.CENTER;
        this.destroy.connect(Gtk.main_quit);
        this.set_resizable(false);
       
        var grid = new Grid();
       
        button = new Button.with_label("Кнопка");
        grid.attach(button, 0, 0, 1, 1);
       
        button.clicked.connect(Signals.my_signal);
       
        label = new Label.with_mnemonic("Это строка");
        grid.attach(label, 1, 0, 1, 1);
       
        this.add(grid);
    }
  }
}

Signals.vala
Код: (vala) [Выделить]
using GUI;

namespace Signals
{
  public void my_signal()
  {
    GUI.label.set_text("Я новая строка");
  }
}

Sample.vala
Код: (vala) [Выделить]
using GUI;

public static int main (string[] args)
{
  Gtk.init (ref args);

  var window = new GUI_Appl();
  window.show_all();

  Gtk.main();
 
  return 0;
}

собирать всё так
valac --pkg gtk+-3.0 GUI.vala Sample.vala Signals.vala --output sample

Пользователь решил продолжить мысль 11 Ноября 2014, 15:22:44:
Только не кошерно как-то, объявлять поля для всеобщего обозрения, если разберусь как по другому сделать, отпишусь
« Последнее редактирование: 11 Ноября 2014, 15:22:44 от S9 »
Burning on the flame
Played the waiting game

Оффлайн alsoijw

  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Re: обработчики событий в Vala
« Ответ #5 : 11 Ноября 2014, 15:43:53 »
с английским более-менее, но это я уже проверял:)

Пользователь решил продолжить мысль [time]11 Ноябрь 2014, 16:19:41[/time]:
извиняюсь, тупанул, объявив Label в конструкторе. Объявив в namespace всё норм заработало:)
собирать всё так
valac --pkg gtk+-3.0 GUI.vala Sample.vala Signals.vala --output sample

Только не кошерно как-то, объявлять поля для всеобщего обозрения, если разберусь как по другому сделать, отпишусь
Так если знаешь, то неужели не понимаешь? Доступ к приватному элементу запрещён.
В каком конструкторе о_О :idiot2:
Это что туториал???

Прочитай про области видимости.

public
No restrictions to access
private
Access is limited to within the class/struct definition. This is the default if no access modifier is specified
protected
Access is limited to within the class definition and any class that inherits from the class
internal
Access is limited exclusively to classes defined within the same package


Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн man0ngi

  • Новичок
  • *
  • Сообщений: 10
    • Просмотр профиля
Re: обработчики событий в Vala
« Ответ #6 : 11 Ноября 2014, 18:09:54 »
Только не кошерно как-то, объявлять поля для всеобщего обозрения, если разберусь как по другому сделать, отпишусь
И ещё на заметку.
Если вам нужны сигналы - используйте модификатор signal. Напрямую через namespace обращаться к элементам формы неверно. В Vala используйте замыкания ( () => {} ), в которых вызывайте нужную функцию с необходимыми параметрами. И в этой нужной функции уже меняйте состояние приложения.

Оффлайн alsoijw

  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Re: обработчики событий в Vala
« Ответ #7 : 11 Ноября 2014, 18:27:26 »
man0ngi, он хочет вынести обработчики в отдельный файл.
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн S9

  • Автор темы
  • Участник
  • *
  • Сообщений: 163
  • Волшебник
    • Просмотр профиля
Re: обработчики событий в Vala
« Ответ #8 : 11 Ноября 2014, 20:18:12 »
Так если знаешь, то неужели не понимаешь? Доступ к приватному элементу запрещён.
В каком конструкторе о_О :idiot2:
Это что туториал???

было так
Код: (vala) [Выделить]
namespace GUI
{
  public class GUI_Appl : Window
  {
    public GUI_Appl ()
    {
        ***
        Label label;
        Button button;
        ***
    }
  }
}

а стало так
Код: (vala) [Выделить]
namespace GUI
{
  public Label label;
  public Button button;
  public class GUI_Appl : Window
  {
    public GUI_Appl ()
    {
        ***
    }
  }
}
по моему, код находился в конструкторе:) ну если я не прав, то поправьте меня:D

И ещё на заметку.
Если вам нужны сигналы - используйте модификатор signal. Напрямую через namespace обращаться к элементам формы неверно. В Vala используйте замыкания ( () => {} ), в которых вызывайте нужную функцию с необходимыми параметрами. И в этой нужной функции уже меняйте состояние приложения.
спасибо, я примерно это и хотел сделать:) сейчас хочу тоже самое через сигналы реализовать, чтобы сохранялась инкапсуляция
P.S. Если не ошибаюсь, то ( () => {} ) вроде лямбда-функции называются, хотя точно не уверен

man0ngi, он хочет вынести обработчики в отдельный файл.
вообщето, в более-менее больших прогах так и надо делать (ну на мой взгляд), и для этих целей как раз подходит концепция сигналов

Так если знаешь, то неужели не понимаешь?
извиняюсь, тупанул
по моему я ответил на ваш вопрос ещё несколько сообщений назад
Burning on the flame
Played the waiting game

Оффлайн alsoijw

  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Re: обработчики событий в Vala
« Ответ #9 : 11 Ноября 2014, 20:35:23 »
Ты их в пространство имён вынес, из класса. В конструкторе ты не сможешь объявить private.
Определись - тебе нужно выносить в отдельный файл или нет.
ЗЫ они же лямбда они же замыкания они же функциональные литералы они же анонимные методы.
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн S9

  • Автор темы
  • Участник
  • *
  • Сообщений: 163
  • Волшебник
    • Просмотр профиля
Re: обработчики событий в Vala
« Ответ #10 : 11 Ноября 2014, 22:33:01 »
Ты их в пространство имён вынес, из класса. В конструкторе ты не сможешь объявить private.
alsoijw, я понимаю, что такое пространства имён, классы, конструкторы и прочие штуки из ООП

Определись - тебе нужно выносить в отдельный файл или нет.
нужно выносить. Ибо файл с отрисовкой GUI у меня занимает около 1000 строк, и если я туда ещё и обработчики прилеплю, то вообще плохо будет

ЗЫ они же лямбда они же замыкания они же функциональные литералы они же анонимные методы.
а за ликбез спасиб, до это точно был уверен что анонимные методы и лямбды одно и тоже, оказывается есть ещё синонимы этого определения
Burning on the flame
Played the waiting game

Оффлайн alsoijw

  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Re: обработчики событий в Vala
« Ответ #11 : 11 Ноября 2014, 23:48:51 »
по моему, код находился в конструкторе:) ну если я не прав, то поправьте меня:D
Ты их в пространство имён вынес, из класса. В конструкторе ты не сможешь объявить private.
Если хочешь вынести - лямбда не поможет.
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн S9

  • Автор темы
  • Участник
  • *
  • Сообщений: 163
  • Волшебник
    • Просмотр профиля
Re: обработчики событий в Vala
« Ответ #12 : 12 Ноября 2014, 08:38:41 »
Если хочешь вынести - лямбда не поможет.
в моём понимании лямбды нужны, когда обработчик простой, и не охота на него метод определять.
Например, захотели на поле для ввода сделать маленькую иконку-кнопку, для копирования содержимомго в буфер обмена
Код: (vala) [Выделить]
  ***
var clipboard = Clipboard.get_for_display(this.get_display(), Gdk.SELECTION_CLIPBOARD);
var entry = new Entry();
entry.set_icon_from_icon_name(EntryIconPosition.SECONDARY, "gtk-copy");
entry.icon_press.connect((pos, event) =>
{
  if (pos == EntryIconPosition.SECONDARY)
  {
    if (entry.get_text().length == 0)
    {
      stderr.printf("В поле «entry» совсем ничего нет, что можно скопировать:(\n");
    }
    else
    {
      clipboard.set_text(entry.text, -1);
    }
  }
});
  ***
тут как раз более удобно использовать лямбду. А если обработчик довольно сложный, то тогда его в отдельный метод оформлять.

Лучше скажите, как через сигналы реализовать этот код?
GUI.vala
Код: (vala) [Выделить]
using Gtk;
using Signals;
 
namespace GUI
{
  public Label label;
  public class GUI_Appl : Window
  {
    private Button button;
 
    public GUI_Appl ()
    {
        this.title = "Sample";
        this.window_position = WindowPosition.CENTER;
        this.destroy.connect(Gtk.main_quit);
        this.set_resizable(false);
       
        var grid = new Grid();
       
        button = new Button.with_label("Кнопка");
        grid.attach(button, 0, 0, 1, 1);
       
        button.clicked.connect(Signals.my_signal);
       
        label = new Label.with_mnemonic("Это строка");
        grid.attach(label, 1, 0, 1, 1);
       
        this.add(grid);
    }
  }
}

Signals.vala
Код: (vala) [Выделить]
using GUI;
 
namespace Signals
{
  public void my_signal()
  {
    GUI.label.set_text("Я новая строка");
  }
}

Код: (vala) [Выделить]
using GUI;
 
public static int main (string[] args)
{
  Gtk.init (ref args);
 
  var window = new GUI_Appl();
  window.show_all();
 
  Gtk.main();
 
  return 0;
}
Burning on the flame
Played the waiting game

Оффлайн alsoijw

  • Старожил
  • *
  • Сообщений: 4062
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Re: обработчики событий в Vala
« Ответ #13 : 12 Ноября 2014, 15:53:02 »
S9, пространства имен пока не нужны, все кнопки внеси в класс.
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн S9

  • Автор темы
  • Участник
  • *
  • Сообщений: 163
  • Волшебник
    • Просмотр профиля
Re: обработчики событий в Vala
« Ответ #14 : 13 Ноября 2014, 09:11:49 »
alsoijw пространства имён нужны. Допустим, я в файле GUI.vala решу ещё класс написать, который будет строить GUI для ещё одного окна/вкладки или ещё чего либо?
Но сейчас мозг может взорваться. Вчера выяснил, что модификатор доступа private объявленный в одном пространстве имён предоставляет доступ к элементу из классов, расположенных в других пространствах имён.
т.е.
GUI.vala
Код: (vala) [Выделить]
using Gtk;
using Signals;

namespace GUI
{
  private Label label; 
  private Button button;
 
  public class GUI_Appl : Window
  {   
    public GUI_Appl ()
    {
        /** бла-бла-бла рисуем окно */
        label = new Label.with_mnemonic("Это строка");
    }
  }
}

Signals.vala
Код: (vala) [Выделить]
using GUI;

namespace Signals

   public void callback()
   {
      label.set_text("Сигнал обработан");
   }
}

т.е. я из пространства имён Signals обращаюсь к приватному полю пространства имён GUI.
по идее, если верить https://wiki.gnome.org/Projects/Vala/Tutorial
то private: Access is limited to within the class/struct definition. This is the default if no access modifier is specified
тобишь доступ к label и button ограничен в определении класса/структуры. В моём случае, это namespace GUI. Но у меня к этим элементам обращается метод из другого пространства имён (namespace Signals). По идее, для этого случая должен работать модификатор internal, но никак не private.

Пользователь решил продолжить мысль [time]13 Ноябрь 2014, 10:18:55[/time]:
S9, пространства имен пока не нужны, все кнопки внеси в класс.
и ещё почему нужны пространства имён, это если не обворачивать классы в пространства имён, то
1. Может быть конфликты имён.
2. Не получится разносить классы по разным файлам, по их функциональному назначению. valac просто тупо не будет находить их. Т.е. если не напишу
Код: (vala) [Выделить]
namespace MyNameSpace
{
}
то не смогу использовать из другого файла содержимое MyNameSpace, а если объявлю, то в другом файле просто напишу
Код: (vala) [Выделить]
using MyNameSpace;и могу воспользоваться содержимым MyNameSpace просто обращаясь
Код: (vala) [Выделить]
MyNameSpace.MyClass.my_method();
« Последнее редактирование: 13 Ноября 2014, 09:19:38 от S9 »
Burning on the flame
Played the waiting game

 

Страница сгенерирована за 0.024 секунд. Запросов: 21.