Несколько экземпляров окна в Perl, используя GTK Builder - PullRequest
1 голос
/ 09 марта 2012

Для начала я неопытный сценарист на Perl или использую gtk, но последние две недели я гуглял и изучал, как это сделать. Трудно было просто выяснить, где я могу найти PM для gtk на окнах, а затем еще больше довести его до некоторого подобия «работы». Однако, конечно, все еще были проблемы.

Пропустив вышесказанное, у меня две проблемы. Для небольшого уместного фона я пытаюсь перенести скрипт mirc на xchat, но для этого мне, очевидно, нужно выучить целый «другой язык» ... но в любом случае. Таким образом, две проблемы:

  1. Окно состоит из нескольких кнопок, надписей и текстовых областей. Тем не менее, окно .. «заморожено» во времени, если не нажать на строку заголовка и удерживать. Нажатие на кнопку ничего не делает, даже показывает, что она была нажата, если, конечно, строка заголовка не нажата и не удерживается.

  2. Я понятия не имею, как инициализировать несколько экземпляров одного и того же окна. Я, конечно, пытался исследовать, но его либо нет, либо я просто еще не нашел. Чтобы быть конкретным .. Мой сценарий mirc требует, чтобы существовало несколько экземпляров, но мне нужно, чтобы кнопки для конкретного экземпляра влияли только на этот экземпляр ... и т. Д.

Что касается проблемы 1, я не знаю, важен ли файл .xml glade, поэтому я не буду публиковать его немедленно. Однако я опубликую код, который вызывает его:

my $glade_file = "window3.xml";
my $glade = Gtk2::Builder->new();
$glade->add_from_file($glade_file);

sub charopen {
    my $window = $glade->get_object('window1');
    $glade->connect_signals(undef, $window);
    my $hp_cur = $glade->get_object('HP_Cur');
    $window->set("title"=>$_[0][1]);
    $hp_cur->set("label"=>$ini->val($_[0][1],"HPC"));
    $window->show();
}

1 Ответ

0 голосов
/ 16 июля 2012

Графический дизайн интерфейса основан на обработке событий. Для правильной работы важно зарезервировать поток для обработки пользовательских событий (клавиатура, щелчки мыши ...). Это цель вызова Gtk2->main(), когда пользовательский интерфейс готов принять взаимодействие с пользователем.

Чтобы поток событий вышел из цикла событий, метод обратного вызова может вызвать Gtk2->main_quit()

Gtk2::Builder создает иерархию виджетов Gtk из XML. Чтобы получить несколько экземпляров одного и того же окна, вы должны создать конструктор для каждого из них.

Тогда ваши методы обратного вызова события должны получить информацию о том, какое окно отправило событие, и для этой цели можно использовать параметр $user_data.

Вот кодовое предложение с простым обратным вызовом нажатия кнопки, которое использует Perl-ссылку на хеш, чтобы вы могли передавать столько информации, сколько вам нужно, между кодом создателя окна и обратными вызовами событий:

sub createWindow($)
    my $windowTitle = $_[0];
    my $windowBuilder = Gtk2::Builder->new();
    $windowBuilder->add_from_file($glade_file);
    my $window = $windowBuilder->get_object('window1');
    my $hp_cur = $windowBuilder->get_object('HP_Cur');

    # Create hash with data (alternative: use Class::Struct for better code)
    my %window_user_data = {
        "title" => $windowTitle,
        "window" => $window,
        "hp_cur" => $hp_cur };
    # Pass hash reference as user data
    $windowBuilder->connect_signals(\%window_user_data);

    # prepare interface: set data model into view and then...
    $window->show();
}

# Click callback method defined on a button in window
sub button_click_callback($$) {
    my $button = $_[0];
    my $window_user_data_ref = $_[1];
    # get back data model from view
    print "Click received from button on "
       . $window_user_data_ref->{"title"} . "\n";
}

Существует еще один способ обработки обратных вызовов для каждого окна, но он требует больше навыков Perl: вы можете создать пакет Perl для создания экземпляра объекта для определенного окна и использовать $windowbuilder->connect_signals ($user_data, $windowcallbackinstance). В этом случае такой объект называется контроллером, и вы построили графический интерфейс на основе шаблона Model-View-Controller (MVC) .

...