LINUX.ORG.RU

Как отобразить GtkButton на GtkEdit


0

1

Продолжаю мусолить тему: http://www.linux.org.ru/forum/development/6222194?lastmod=1304519984374#comment-6227462 (комментарий)

Сейчас родитель(GtkEdit) отображается, всё, нормально, но никак не могу «положить» на него кнопку. Вот мой метод gtk_button_entry_map:

static void
gtk_button_entry_map(GtkWidget * widget)
{
	GtkButtonEntry * entry = GTK_BUTTON_ENTRY(widget);
	GtkWidget * b = gtk_button_new_with_label("...");
	if(GTK_WIDGET_REALIZED(widget) && !GTK_WIDGET_MAPPED(widget)) {
		GTK_WIDGET_CLASS(parent_class)->map(widget);
	/*	while (entry->buttons) {
			GList *next = entry->buttons->next;
			gtk_widget_show(GTK_WIDGET(entry->buttons->data));
			entry->buttons = next;
		}
		g_list_first(entry->buttons);*/
		/*
		b->allocation.x = 20;
		b->allocation.y = 0;
		b->allocation.width = 20;
		b->allocation.height = 20;
	
		b->requisition.width = 20;
		b->requisition.height = 20 */
		gtk_widget_set_size_request(b, 20, 20);
	
		gtk_widget_set_parent(b, GTK_WIDGET(entry));
		gtk_widget_map(GTK_WIDGET(b));	
	}
}

Пробовал сделать добавление кнопки на виджет в отдельном методе:

GtkWidget * gtk_button_entry_add_button(GtkButtonEntry * entry, gint alignment)
{
	GtkWidget * b = gtk_button_new_with_label("...");
	entry->buttons = g_list_append(entry->buttons, b);	
	b->allocation.x = 20;
	b->allocation.y = 0;
	b->allocation.width = 20;
	b->allocation.height = 20;
	
	b->requisition.width = 20;
	b->requisition.height = 20;
	
	gtk_widget_set_parent(b, GTK_WIDGET(entry));
	if(GTK_WIDGET_MAPPED(GTK_WIDGET(entry)) && !GTK_WIDGET_MAPPED(b))
		gtk_widget_map(GTK_WIDGET(entry)); 
}
Здесь я явно создаю кнопку, задаю её размер, устанавливаю ей родителя(тот самый GtkEdit) и вызываю map своего виджета, но кнопка всё равно не отображается, что я делаю не так? В своём методе gtк_button_entry_map) я пытался уже явно создать кнопку и расположить её на родителе, тоже не вышло :(

★★★★★

> а мне нужно чтобы была возожность располагать несколько штук подряд, типа как в DevExpress

Что мешает расположить кнопки не на GtkEntry, а рядом, в HBox?

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

Нужно чтобы они лежали на поле ввода, либо как-то их на GtkEntry лепить, либо лепить саму «GtkEntry», т.е рисовать это поле ввода самостоятельно, и потом на нём же рисовать кнопки(это будут не настоящие кнопки, а «рисованные»)

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

Ты не ответил на вопрос. Почему расположение кнопок поверх GtkEntry — это вопрос жизни и смерти?

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

Требуется ввод текста, HBox для этого не подойдёт... хотя, подойдёт, если расположить кнопки за GtkEntry, но это будет не то...

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

но это будет не то

Анонимус принципиально не понимает мазохистов, которые вместо простого и понятного, как три рубля решения:

+-----------+---+
|text|      |...|
+-----------+---+

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

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

Хочу как на картинке: http://www.devexpress.com/Products/NET/Controls/WinForms/Editors/Editors/ButtonEdit.xml И не вижу ничего дурного в том, чтобы сделать для этого нормальный виджет, и не заниматься забиванием гвоздей микроскопом...

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

> заниматься забиванием гвоздей микроскопом...

Вот и не занимайся.

1. Убираешь у GtkEntry бордюр.

2. Упаковываешь его с нужными кнопками в hbox

3. Кладешь всю эту конструкцию в GtkFrame, у которого фон и рамка выставлены в аналогичные у GtkEntry.

4. Внезапный профит!

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

Хороший вариант, спасибо, попробую его. Я думал об этом с самого начала, но посчитал что из-за бордюров будет выглядеть криво и не естественно.

А вообще отображать виджет можно только если он лежит в контейнере? Почему например в это случае не удалось положить кнопку на entry?, ведь вроде и то и то виджет, их можно друг на друга ложить...

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

> А вообще отображать виджет можно только если он лежит в контейнере?

Не только.

Почему например в это случае не удалось положить кнопку на entry?

Не был определен обработчик expose-event у поля ввода, который бы выводил кнопку. Но это так, мелочи. Веселуха начнется при попытке заставить поле забыть про свой кусочек, накрытый кнопкой. Ты походу, вообще не думал над проблемой.

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

Хм... обработчик поля ввода у меня был определён, но он рисовал лишь родительский контрол, путём вызова expose родителя т.е GtkEntry, я не думал что в нём нужно ещё рисовать саму кнопку, думал вызову gtk_show_widget(button) и она отобразится, главное координаты и размер кнопке задать...

Ты походу, вообще не думал над проблемой.


Честно сказать, большого багажа знаний в этой области не имею, если нужно сделать просто интерфейс на базе существующих контролов, то тут ничего сложного, а создавать свои, не пробовал, только начинаю постигать эту «науку». Думал по ходу разберусь что к чему, если что допилю.

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

> Веселуха начнется при попытке заставить поле забыть про свой кусочек, накрытый кнопкой

gtk_entry_set_inner_border() и никакой веселухи.

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

Переделал виджет, унаследовал его от GtkFrame, положил в него GtkHBox, непосредственно в который положил GtkEntry и кнопку, вроде нормально, но кнопка выглядит не айс, из-за «пустоты» вокруг неё: http://www.imagepost.ru/?v=button_3.PNG создаю всё это в методе инициализации:

static void 
gtk_button_entry_init(GtkButtonEntry * entry)
{
	entry->buttons = NULL;
	entry->hbox = gtk_hbox_new(FALSE, 0);
	GtkWidget * ewidget = gtk_entry_new();
	GtkWidget * button = gtk_button_new_with_label("...");
	GtkWidget * check = gtk_check_button_new();
	gtk_frame_set_shadow_type(GTK_FRAME(entry), GTK_SHADOW_IN);
	gtk_container_add(GTK_CONTAINER(entry),GTK_WIDGET(entry->hbox));
	
	gtk_entry_set_has_frame(GTK_ENTRY(ewidget), FALSE);
	gtk_box_pack_start(GTK_BOX(entry->hbox), ewidget, TRUE, TRUE, 0);
	gtk_box_pack_end(GTK_BOX(entry->hbox), button, FALSE, TRUE, 0);

	
}

структура моего контрола:

typedef struct {
	GtkFrame parent;
	GtkHBox * hbox;
	GList * buttons;
	
} GtkButtonEntry;

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

set_inner_border меняет внутренний размер виджета, т.е если сделать так (в общем):

gtk_widget_get_size_request(entry, &requisition); //requisition->width = 100

А потом изменим правую границу GtkEntry:

border->right = 30;
gtk_entry_set_inner_border(entry, border)
то requisition->width станет равным 130, что создаст проблемы при следующем использованиии функции :)

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