LINUX.ORG.RU

Статическая линковка UI, собранных в Glade


0

1

У меня такой вопрос: UI, созданные при помощи Glade, загружаются в программу в процессе ее выполнения. Т.е. нужно жестко прописывать пути и следить, чтобы файл не удалили, что неудобно. Возможно ли на этапе компиляции включать интерфейс в получаемый бинарник? Или все-таки надежнее весь интерфейс описывать ручками?

И еще есть маленький вопросец: КОИ8-Р в gtk-шных приложениях не поддерживается?

☆☆☆☆☆

> КОИ8-Р в gtk-шных приложениях не поддерживается?

Нет, ибо в gtk+ везде юникод, что очень хорошо.

gtkbuilder-файлы просто следует класть куда-либо в /usr/share (или куда там полагается по Filesystem Hierarchy Standard). Не стоит опасаться того, что кто-то удалит этот файл.

Если совсем хочется - то можно как-либо вшивать их в исполняемый файл и использовать загрузку из строки.

dmitry_vk ★★★
()
Ответ на: комментарий от Eddy_Em

>UI, созданные при помощи Glade, загружаются в программу в процессе ее выполнения. Т.е. нужно жестко прописывать пути и следить, чтобы файл не удалили, что неудобно.

Придется внедрять костыли в виде юникода...

Юзал бы Qt, не знал бы проблем

annulen ★★★★★
()
Ответ на: комментарий от annulen

Зато там есть куча других проблем: как прикрутить кути к сям? Как сделать, чтобы кутишные программы не были такими уродливыми? И т.д., и т.п.

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

>Зато там есть куча других проблем: как прикрутить кути к сям?

скомпилировать свои си как кресты, делов-то) ну только если у тебя там совсем суровый с99. Исходники, не относящиеся к гуям, естественно не трогаются

Как сделать, чтобы кутишные программы не были такими уродливыми?

Писать их неуродливо / пересмотреть свои критерии уродливости и т.п.

annulen ★★★★★
()

Ладно, раз уж никаких вариантов нет, буду все элементы прописывать «ручками» :(

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

>Вот и хотелось бы узнать: как их «вшивать» в исполняемый файл.

Присвоить переменной содержимое glade-файла и скормить данную переменную GtkBuilder'у. «Присваивание» можно поручить какому-нибудь cmake'у или autohell'у.

fat_angel ★★★★★
()

как-то так

echo "conts gchar ui[] = $(sed -r 's/(^.*$)/\"&\"/' interface.ui);" > interface.ui.h

потом в коде

#include "interface.ui.h"
...
gtk_builder_load_from_string(builder, ui);
...
ananas ★★★★★
()
Ответ на: комментарий от ananas

чтобы заэкранировать кавычки в glade-овском файле

echo "conts gchar ui[] = $(sed -r 's/\"/\\\"/g;s/(^.*$)/\"&\"/' interface.ui);" > interface.ui.h

ananas ★★★★★
()
Ответ на: комментарий от Eddy_Em

в принципе, туда можно добавить еще убиение лишних пробелов, комментариев и прочего ненужного барахла. вроде в lxde где-то была утилитка для чистки glade-овского xml

ananas ★★★★★
()
Ответ на: комментарий от ananas

Ну, почистить его и sed'ом или awk каким-нибудь можно...

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от ananas

Что-то не выходит. Сделал make-файл:

APPLICATION	= example
C.SRCS		= example.c
UI.SRC		= example.ui
CC	= gcc
DEPS	= gtk+-2.0 gtkglext-1.0 gtkglext-x11-1.0
CFLAGS	= -Wall -Werror `pkg-config --cflags $(DEPS)`
LIBS	= `pkg-config --libs $(DEPS)`
OBJS	= $(C.SRCS:.c=.o)
all: $(APPLICATION)
UI: $(UI.SRC)
	echo "const gchar ui[] = `sed -r 's/\"/\\\\\"/g;s/(^.*$$)/\"&\"/' $(UI.SRC)` ;" > ui.h
$(APPLICATION): UI $(OBJS)
	gcc $(CFLAGS) $(LIBS) $(OBJS) -o $@
clean:
	rm -f $(APPLICATION) *.o
Компилируется, но при запуске выдает ошибку:
(example:30628): Gtk-CRITICAL **: gtk_builder_add_from_string: assertion `error == NULL || *error == NULL' failed

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от ananas
#include <stdlib.h>
#include <gtk/gtk.h>
#include "ui.h"

void on_window_destroy (GtkObject *object, gpointer user_data){
    gtk_main_quit ();
}

int main (int argc, char *argv[]){
    GtkBuilder      *builder; 
    GtkWidget       *window;
    GError *err;

    gtk_init (&argc, &argv); 
    printf("str:\n%s\nsize=%d\n", ui, sizeof(ui));
    builder = gtk_builder_new();
    if(!gtk_builder_add_from_string(builder, ui, sizeof(ui), &err)){
    	fprintf(stderr, "%s  (%d)\n", err->message, err->code); exit(-1);}
    window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
    gtk_builder_connect_signals (builder, NULL);

    g_object_unref (G_OBJECT (builder));
        
    gtk_widget_show (window);                
    gtk_main ();

    return 0;
}

Не загружает даже ui для пустого окна :(

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

err перед использованием надо обнулять. т.е. обявляй ее как GError *err = NULL;

и перед повторным использованием ей тоже надо NULL загонять

и еще, gtk_main_quit можно использовать напрямую как callback, без оберток. и к флагам линковки добавляй -export-dynamic

ananas ★★★★★
()
Ответ на: комментарий от Eddy_Em

И что интересно, с тем же ui, но функцией gtk_builder_add_from_file работает...

Eddy_Em ☆☆☆☆☆
() автор топика

Фух! Нашел проблему: строка с ui должна иметь тип const gchar*, а не const gchar const*; а чтобы ее размер не считать, в функции gtk_builder_add_from_string надо указывать вместо размера -1. Вот что получилось:

#include <stdlib.h>
#include <gtk/gtk.h>
#include "ui.h"

void on_window_destroy (GtkObject *object, gpointer user_data){
    gtk_main_quit ();
}
int main (int argc, char *argv[]){
    GtkBuilder      *builder; 
    GtkWidget       *window;
    GError *err = NULL;
    gint i;
    gtk_init (&argc, &argv); 
    printf("str:\n%s\nsize=%d\n", ui, sizeof(ui));
    builder = gtk_builder_new();
    if(!(i=gtk_builder_add_from_string(builder, ui, -1, &err))){
    	g_warning("%d\n", err->code); exit(-1);}
    printf("\n\ni=%d\n\n",i);
    window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
    gtk_builder_connect_signals (builder, NULL);
    g_object_unref (G_OBJECT (builder)); 
    gtk_widget_show(window);
    gtk_main ();
    return 0;
}
Остается доработать Makefile, чтобы он вызывал sed не каждый раз, а лишь когда glade'овский ui-файл изменится (пока как это сделать не догадываюсь). Сейчас Makefile такой:
APPLICATION	= example
C.SRCS		= example.c
UI.SRC		= example.ui

CC	= gcc
DEPS	= gtk+-2.0 gtkglext-1.0 gtkglext-x11-1.0
CFLAGS	= -Wall -Werror `pkg-config --cflags $(DEPS)`
LIBS	= -export-dynamic `pkg-config --libs $(DEPS)`

OBJS	= $(C.SRCS:.c=.o)

all: $(APPLICATION)

$(APPLICATION).o: UI

UI: $(UI.SRC)
	echo "const gchar *ui = `sed -r 's/\"/\\\\\"/g;s/(^.*$$)/\"&\"/' $(UI.SRC)` ;" > ui.h

$(APPLICATION): UI $(OBJS)
	gcc $(CFLAGS) $(LIBS) $(OBJS) -o $@

clean:
	rm -f $(APPLICATION) *.o

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

пока как это сделать не догадываюсь

ui.h : example.glade
      echo ...

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

ananas ★★★★★
()
Ответ на: комментарий от ananas

Переделал Makefile:

APP	= example
C.SRCS	= example.c
UI.SRC	= example.ui

CC	= gcc
DEPS	= gtk+-2.0 gtkglext-1.0 gtkglext-x11-1.0
CFLAGS	= -Wall -Werror `pkg-config --cflags $(DEPS)`
LIBS	= -export-dynamic `pkg-config --libs $(DEPS)`
OBJS	= $(C.SRCS:.c=.o)
all: $(APP)
$(APP).o: ui.h $(APP).c
	gcc $(CFLAGS) $(APP).c -c -o $(APP).o
$(APP): $(OBJS)
	gcc $(CFLAGS) $(LIBS) $(OBJS) -o $(APP)
ui.h: $(UI.SRC)
	echo "const gchar *ui = `sed -r 's/\"/\\\\\"/g;s/(^.*$$)/\"&\"/' $(UI.SRC)` ;" > ui.h
clean:
	rm -f $(APP) *.o ui.h
Теперь работает как надо!

Еще раз огромное спасибо за советы!

Eddy_Em ☆☆☆☆☆
() автор топика

И опять я со своим glade. Разбираясь в чужом коде (который использую как пример) натолкнулся на C-файлы, сгенерированные glade-2. А как бы такое в glade-3 сделать? Или уже все - поезд уехал, и glade больше не позволяет генерировать код?

Eddy_Em ☆☆☆☆☆
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.