[php-gtk-ru] Сохранение позиции окна при выходе, восстановление при запуске

23 views
Skip to first unread message

ASLok

unread,
Apr 18, 2010, 6:00:21 AM4/18/10
to Русское сообщество PHP-GTK
Есть странный глюк, у меня окно выставлено по центру, но когда получаю
его позицию по сигналу GtkWindow GtkObject destroy то возвращаемая
позиция всегда как будто окно только что создано по-центру. Может я
чего-то не понимаю :( Обошел этот глюк, но есть мертвый пиксель - если
вручную поставить окно в начальную позицию по-центру, то новая позиция
по-центру сохранена не будет :( Плюс к тому же, позиция сохраняется
только если нажать кнопку выход (в данном случае это меню Файл-Выход
или Ctrl+Q). Можно убрать эту функцию сохранения с выхода и повесить
на отдельный пункт меню "Сохранить позицию", еще можно сохранять
позицию по таймеру. Но с мертвым пикселом все равно как-то неизящьно
получилось :(


#!/usr/bin/php
<?php
define('N', "\n\r");
define('n', "\n");
define('BASE', dirname(__FILE__) . '/');
define('APP_NAME', 'window1');


function on_ok_clicked()
{
global $entry1, $label2;
$label2->set_text(md5(trim($entry1->get_text())));
}


function on_get_weather_clicked()
{
global $label4;
$url_arr = get_headers_content('http://www.gismeteo.ua/city/daily/
5093/');

$preg_match = substr($url_arr['content'],
strpos($url_arr['content'], '<td
class="deg"'));

$preg_match = substr($preg_match,
0,
strpos($preg_match, '</td>'));

$preg_match = trim(str_replace(array ('&deg;', ' ', N, n),
array ('', '', ' ', ' '),
strip_tags($preg_match)));

log_message('debug',
'Получена строка "' . $preg_match . '"');

$label4->set_text($preg_match);
}


function on_quit_clicked()
{
quit();
}


function quit()
{
global $config;
save_config($config);
Gtk::main_quit();
}


$glade1 = new GladeXML(BASE . APP_NAME . '.glade');
$glade1->signal_autoconnect();

$window1 = $glade1->get_widget('window1');

$label2 = $glade1->get_widget('label2');

$entry1 = $glade1->get_widget('entry1');

$label4 = $glade1->get_widget('label4');

$config = load_config();

$window1->show_all();

Gtk::main();


function save_config($groups = false)
{
global $window1;
if (!is_array($groups))
{
$window1_pos = $window1->get_position();

$groups = array ('General' => array ('Position_x' =>
$window1_pos[0],
'Position_y' =>
$window1_pos[1]),
'Default' => array ('Position_x' =>
$window1_pos[0],
'Position_y' =>
$window1_pos[1]));

}
else
{
$groups = before_save_config($groups);
}

$out = '';
foreach ($groups as $group_name => $group)
{
$out .= '[' . $group_name . ']' . N;
foreach ($group as $value_name => $value)
{
$out .= $value_name . ' = ' . $value . N;
}
}
file_put_contents(BASE . APP_NAME . '.ini', $out);
}


function before_save_config($config)
{
global $window1;
$window1_pos = $window1->get_position();

if ($window1_pos[0] != $config['Default']['Position_x'] ||
$window1_pos[1] != $config['Default']['Position_y'])
{
$config['General']['Position_x'] = $window1_pos[0];
$config['General']['Position_y'] = $window1_pos[1];
}

return ($config);
}


function load_config()
{
$config_file_name = BASE . APP_NAME . '.ini';
if (!file_exists($config_file_name))
{
save_config();
}
after_load_config($config = parse_ini_file($config_file_name,
true));
return ($config);
}


function after_load_config($config)
{
global $window1;

$window1->move($config['General']['Position_x'],
$config['General']['Position_y']);
}

function log_message($type, $message)
{
print ($type . ': ' . $message . N);
}


function get_headers_content($url, $user_agent = null)
{
$socket_time_out = 60;
$max_try = 20;


$set_cookie = array ();
$time_start = explode(' ', microtime());
$try_id = 0;
$url_result = false;
$request_counter = 0;
log_message('debug',
'Получаем содержимое страницы "' . $url . '"');
do
{
$url_parts = parse_url($url);
if (!is_array($url_parts))
{
break;
}
$url_scheme = isset ($url_parts['scheme']) ?
$url_parts['scheme'] :
'http';
$url_host = isset ($url_parts['host']) ?
$url_parts['host'] : '';
$url_path = isset ($url_parts['path']) ?
$url_parts['path'] : '/';
$url_port = isset ($url_parts['port']) ?
intval($url_parts['port']) :
80;
if (isset ($url_parts['query']) && $url_parts['query'] !=
'')
{
$url_path .= '?' . $url_parts['query'];
}
$url_port_request = $url_port == 80 ? '' : ":$url_port";
$user_agent =
$user_agent == null ?
'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;
SV1)' :
strval($user_agent);
$get_request = "GET $url_path HTTP/1.0\r\n" .
"Host: $url_host$url_port_request\r\n" .
"Accept-Encoding: identity\r\n" .
"User-Agent: $user_agent\r\n";
foreach ($set_cookie as $domain => $cookie)
{
if (substr_count($url_host, $domain) &&
(!isset ($cookie['path']) ||
(!($cookie_path = rtrim($cookie['path'], '/')) ||
substr_count($url_path, $cookie_path))))
{
$get_request .= 'Cookie: ';
foreach ($cookie as $cookie_key => $cookie_val)
{
if ($cookie_key != 'expires' && $cookie_key !=
'path' &&
$cookie_key != 'domain' && $cookie_key !=
'secure')
{
$get_request .= $cookie_key . '=' .
$cookie_val . '; ';
}
}
$get_request = rtrim($get_request, '; ') . "\r\n";
break;
}
}
$get_request .= "\r\n";
$error_no = $error_str = null;
$socket = @fsockopen($url_host, $url_port, $error_no,
$error_str, $socket_time_out);
$request_counter++;
log_message('debug',
'Открываем сокет для "' . $url_host . ':' .
$url_port . '"');
if ($socket)
{
log_message('debug',
'Сокет открыт, отправляем запрос: ' .
$get_request);
if (($response = fputs($socket, $get_request)))
{
socket_set_timeout($socket, $socket_time_out);
$header = '';
$socket_status = socket_get_status($socket);
while (!feof($socket) && !
$socket_status['timed_out'] &&
trim($temp = fgets($socket)))
{
$header .= $temp;
$socket_status = socket_get_status($socket);
}

$res = null;
if (preg_match('~http\/(\d+\.\d+)\s+(\d+)\s+(.*)\s*\
\r\\n~si',
$header, $res))
{
log_message('debug',
'Получен ответ сервера: "' .
$res[2] . '"');

$server_code = $res[2];
}
else
{
log_message('debug',
'Код ответа сервера не определен');

break;
}

if ($server_code == 200)
{
$content = '';
$socket_status = socket_get_status($socket);
while (!feof($socket) && !
$socket_status['timed_out'])
{
$content .= fgets($socket, 1024 * 8);
$socket_status = socket_get_status($socket);
}
log_message('debug',
'Содержимое получено, сделано ' .
$request_counter . ' запросов');
$time_end = explode(' ', microtime());
$time_total = ($time_end[0] + $time_end[1]) -
($time_start[0] + $time_start[1]);
$url_result['header'] = $header;
$url_result['url'] = $url;
$url_result['content'] = $content;
$url_result['time'] = $time_total;
$url_result['request_counter'] =
$request_counter;
}
elseif ($server_code == 301 || $server_code == 302)
{
if (preg_match('~location\:\s*(.*?)\\r\\n~si',
$header,
$res))
{
$redirect_url = rtrim($res[1]);
log_message('debug',
'Страница перемещена, ' .
'найден новый адрес: "' .
$redirect_url . '"');
$url_parts = parse_url($redirect_url);

if (isset ($url_parts['scheme']) &&
isset ($url_parts['host']))
{
$url = $redirect_url;
}
else
{
$location = substr($url_path, -1) !=
'/' ?
dirname(substr($url_path,
1)) . '/' :
'';
$url = $url_scheme . '://' . $url_host .
'/' .
$location . ltrim($redirect_url,
'/');
}

if (preg_match_all('~Set-Cookie:\s([^
\n]*)~i',
$header,
$res))
{
foreach ($res[1] as $res)
{
$attributs = explode(';',
trim($res));

foreach ($attributs as $value)
{
$tmp_arr = explode('=',
trim($value));
if (!count($tmp_arr))
{
continue;
}
elseif (count($tmp_arr) == 1)
{
$attr = reset($tmp_arr);
$val = '';
}
else
{
list($attr, $val) = $tmp_arr;
}
$set_cookie[$url_host]
[trim($attr)] =
trim($val);
}
}
if (isset ($set_cookie[$url_host]
['domain']))
{
foreach ($set_cookie[$url_host] as
$key =>

$val)
{
$set_cookie[
$set_cookie[$url_host]['domain']
][$key] = $val;
}
unset($set_cookie[$url_host]);
}
}
}
else
{
log_message('debug',
'Страница перемещена, ' .
'новый адрес не найден');
break;
}
}
}
fclose($socket);
}
else
{
log_message('debug',
'Сокет не может быть отрыт');
}
sleep(2);
$try_id++;
}
while ($try_id <= $max_try && $url_result === false);
return ($url_result);
}
?>

--
Вы получили это сообщение, поскольку подписаны на группу Русское сообщество PHP-GTK.

Чтобы добавлять сообщения в эту группу, отправьте письмо по адресу php-g...@googlegroups.com.
Чтобы отменить подписку на эту группу, отправьте сообщение по адресу php-gtk-ru+...@googlegroups.com.
О дополнительных функциях можно узнать в группе по адресу http://groups.google.com/group/php-gtk-ru?hl=ru.

Shecspi

unread,
Apr 18, 2010, 6:35:37 AM4/18/10
to Русское сообщество PHP-GTK
Метод get_position() возвращает именно координаты начального положения
окна, как и get_resizable() для размеров. Именно с последним у меня
возникали проблемы при работе над FlightFiles, когда необходимо было
реаилизовать сохранение размеров окна. Как я с этим справился - не
помню, но Вы можете посмотреть в исходном коде, может аналогично можно
и с координатами окна.

GoTLiuM InSPiRiT

unread,
Apr 18, 2010, 6:53:27 AM4/18/10
to php-g...@googlegroups.com
Посмотрел FlightFiles, но вот исходных размеров окна при закрытии он не запоминает.
При чем если даже ресайзить, или жать на крестик.
А так прикольно сделано ;-)
Сам мечтал написать нормальный файл менеджер для себя,
но честно говоря меня Krusader устроил))

18 апреля 2010 г. 15:35 пользователь Shecspi <she...@gmail.com> написал:



--
Best regards, GoTLiuM InSPiRiT.
E-mail: sup...@metall-zone.com
Site:   www.metall-zone.com
Phone:  +998902982884

GoTLiuM InSPiRiT

unread,
Apr 18, 2010, 7:22:32 AM4/18/10
to php-g...@googlegroups.com
К стати, посмотрел, подумал, и даже решил это включить в фреймворк.
Вот как это делается:
добавим событие delete-event
после создадим метод или функцию, а лучше две)
в первой добавим тайм-аут, скажем 2 сек
а во втором просто узнаем исходную позицию окна)))
а после при загрузке окна двигаем в нужную позицию)



18 апреля 2010 г. 15:53 пользователь GoTLiuM InSPiRiT <got...@gmail.com> написал:

GoTLiuM InSPiRiT

unread,
Apr 18, 2010, 7:30:36 AM4/18/10
to php-g...@googlegroups.com
забыл про событие window-state-event.
при развёртке или сворачивании окна.
для этого события и нужен тайм-аут.
потому как если сначала получить позицию, то выходит получаем исходную.
но это на случай если выключат свет.


18 апреля 2010 г. 16:22 пользователь GoTLiuM InSPiRiT <got...@gmail.com> написал:

Shecspi

unread,
Apr 18, 2010, 8:33:36 AM4/18/10
to Русское сообщество PHP-GTK
0_о Не запоминает?! Вот это новость(( А я всегда думал, что
запоминает.
Максим, этой функции действительно не было?

GoTLiuM InSPiRiT:


> Посмотрел FlightFiles, но вот исходных размеров окна при закрытии он не
> запоминает.
> При чем если даже ресайзить, или жать на крестик.
> А так прикольно сделано ;-)
> Сам мечтал написать нормальный файл менеджер для себя,
> но честно говоря меня Krusader устроил))
>
> 18 апреля 2010 г. 15:35 пользователь Shecspi <she...@gmail.com> написал:
>
> > Метод get_position() возвращает именно координаты начального положения
> > окна, как и get_resizable() для размеров. Именно с последним у меня
> > возникали проблемы при работе над FlightFiles, когда необходимо было
> > реаилизовать сохранение размеров окна. Как я с этим справился - не
> > помню, но Вы можете посмотреть в исходном коде, может аналогично можно
> > и с координатами окна.
> >
> > --
> > Вы получили это сообщение, поскольку подписаны на группу Русское сообщество
> > PHP-GTK.
> >
> > Чтобы добавлять сообщения в эту группу, отправьте письмо по адресу
> > php-g...@googlegroups.com.
> > Чтобы отменить подписку на эту группу, отправьте сообщение по адресу

> > php-gtk-ru+...@googlegroups.com<php-gtk-ru%2Bunsu...@googlegroups.com>

Max Khilo

unread,
Apr 18, 2010, 2:57:43 PM4/18/10
to php-g...@googlegroups.com
Такой функции нет :-). Для очистки совести даже поискал строки с get_position() и get_resizable().
Может это где-то осело в черновиках к релизу?
Я когда-то думал насчет этой ф-сти, но потом забросил, т.к. это надо дописывать и конфг. файл БД.
Можно добавить в список задач на будущие.

Shecspi

unread,
Apr 18, 2010, 4:19:49 PM4/18/10
to Русское сообщество PHP-GTK
Странно, я точно помню, что искал способы решения этой проблемы.
Видимо, забыл внести обновления в основную ветку.

ASLok

unread,
Apr 19, 2010, 3:38:44 AM4/19/10
to Русское сообщество PHP-GTK
Нет, ну если я беру get_position() не по сигналу GtkWindow GtkObject
destroy, а по нажатию кнопки, то get_position() возвращает верные
данные! Недостаток моего решения в том, что по нажатию крестика в
заголовке окна я делаю выход по GtkWindow GtkObject destroy, а именно
по этому сигналу get_position() возвращает неверные данные, начальную
позицию :( А если я вызываю ту же ф-ию quit() по File-Quit (Ctrl+Q)
все отлично отрабатывает. Может есть другие сигналы, которые издаются
по нажатию крестика в заголовке? Можно ещё на них потестить

Shecspi

unread,
Apr 19, 2010, 5:30:32 AM4/19/10
to php-g...@googlegroups.com
Сигнал 'destroy' вызывается именно при разрушении окна, а при его
закрытии издается 'delete-event'. Попробуйте использовать этот сигнал.

19.04.10, ASLok<aslo...@gmail.com> написал(а):


--

------------------------

С уважением, Вавилов Егор aka Shecspi.

ASLok

unread,
Apr 19, 2010, 9:44:54 AM4/19/10
to Русское сообщество PHP-GTK
Спасибо, работает отлично! Повесил сохранение на выход, а выход на
GtkWindow GtkWidget
delete-event. Но все равно при выходе пишет "Аварийный останов" в
консоль

On 19 апр, 12:30, Shecspi <shec...@gmail.com> wrote:
> Сигнал 'destroy' вызывается именно при разрушении окна, а при его
> закрытии издается 'delete-event'. Попробуйте использовать этот сигнал.
>

> 19.04.10, ASLok<aslok...@gmail.com> написал(а):

> О дополнительных функциях можно узнать в группе по адресуhttp://groups.google.com/group/php-gtk-ru?hl=ru.

Shecspi

unread,
Apr 19, 2010, 10:17:05 AM4/19/10
to php-g...@googlegroups.com
А как осуществляете выход из программы?

19.04.10, ASLok<aslo...@gmail.com> написал(а):

ASLok

unread,
Apr 19, 2010, 10:49:20 AM4/19/10
to Русское сообщество PHP-GTK
Сейчас on_quit_clicked() висит так же на кнопке выход и GtkWindow
GtkWidget delete-event, там по итогу вызывается Gtk::main_quit()

function on_quit_clicked()
{
log_message('debug',
'Вызвана ф-ия выхода');
quit();
}


function quit()
{
log_message('debug',
'Сохраняем конфиг');
save_config();
log_message('debug',
'Выход');
Gtk::main_quit();
}

$config = false;

load_config();

$window1->show_all();

Gtk::main();


function save_config()
{
global $config;
if (!is_array($config))
{
log_message('debug',
'Конфиг файл будет создан');
$config = array ('General' => array ('My_text' => ''));
}

before_save_config();

$out = '';
foreach ($config as $group_name => $group)


{
$out .= '[' . $group_name . ']' . N;
foreach ($group as $value_name => $value)
{

if ($value_name != 'My_text')
{


$out .= $value_name . ' = ' . $value . N;
}
}
}

if (md5($config['General']['My_text']) != md5($out))
{
$config['General']['My_text'] = $out;


file_put_contents(BASE . APP_NAME . '.ini', $out);
}
}


function before_save_config()
{
global $window1, $config;
$window1_pos = $window1->get_position();

$config['General']['Position_x'] = $window1_pos[0];
$config['General']['Position_y'] = $window1_pos[1];
}


function load_config()
{
global $config;
log_message('debug',
'Загружаем сохраненный конфиг');


$config_file_name = BASE . APP_NAME . '.ini';
if (!file_exists($config_file_name))
{

log_message('debug',
'Конфиг не найден');
save_config();
}
$config = parse_ini_file($config_file_name, true);
after_load_config();
$config['General']['My_text'] =
file_get_contents($config_file_name);
}


function after_load_config()
{
global $window1, $config;

$window1->move($config['General']['Position_x'],
$config['General']['Position_y']);

log_message('debug',
'Перемещаем окно к ' . $config['General']
['Position_x'] .
'x' . $config['General']['Position_y']);
}

function log_message($type, $message)
{
print ($type . ': ' . $message . N);
}

On 19 апр, 17:17, Shecspi <shec...@gmail.com> wrote:
> А как осуществляете выход из программы?
>

> 19.04.10, ASLok<aslok...@gmail.com> написал(а):

> О дополнительных функциях можно узнать в группе по адресуhttp://groups.google.com/group/php-gtk-ru?hl=ru.

Shecspi

unread,
Apr 19, 2010, 11:25:58 AM4/19/10
to php-g...@googlegroups.com
А если попробовать на delete-event повесить сохранение настроек, а на
destroy - выход?

19.04.10, ASLok<aslo...@gmail.com> написал(а):

ASLok

unread,
Apr 19, 2010, 11:41:15 AM4/19/10
to Русское сообщество PHP-GTK
Поменял на

function on_quit_clicked()
{
log_message('debug',
'Вызвана ф-ия выхода');

log_message('debug',
'Сохраняем конфиг');
save_config();
quit();
}


function quit()
{
log_message('debug',

'Выход');
Gtk::main_quit();
}

Повесил on_quit_clicked() на кнопку выход, quit() на destroy,
save_config на delete-event, выключил сохранение по событию configure-
event. Сохраняет по прежнему отлично, но "Аварийный останов" всё равно
пишет. Вот из консоли:

$ ./PHP-GTK/window1.php
PHP Warning: Module 'SQLite' already loaded in Unknown on line 0
debug: Загружаем сохраненный конфиг
debug: Перемещаем окно к 761x665
debug: Выход
Аварийный останов


On 19 апр, 18:25, Shecspi <shec...@gmail.com> wrote:
> А если попробовать на delete-event повесить сохранение настроек, а на
> destroy - выход?
>

> 19.04.10, ASLok<aslok...@gmail.com> написал(а):

> Вы получили это сообщение, поскольку...
>
> продолжение >>

Shecspi

unread,
Apr 19, 2010, 12:08:23 PM4/19/10
to php-g...@googlegroups.com
А что PHP в логи пишет?

19.04.10, ASLok<aslo...@gmail.com> написал(а):

ASLok

unread,
Apr 19, 2010, 1:01:37 PM4/19/10
to php-g...@googlegroups.com
Всё только в консоль

$ ./PHP-GTK/window1.php
PHP Warning: Module 'SQLite' already loaded in Unknown on line 0
debug: Загружаем сохраненный конфиг
debug: Перемещаем окно к 761x665
debug: Выход
Аварийный останов

19 апреля 2010 г. 19:08 пользователь Shecspi <she...@gmail.com> написал:

Reply all
Reply to author
Forward
0 new messages