LINUX.ORG.RU

Проблема при использовании GTK+ под Windows

 ,


1

1

Здравствуйте! Проблема при использовании GTK+ под Windows. Пожалуйста, помогите чайнику - подскажите, что я не учитываю.

Поскольку есть желание в будущем перейти на Linux, интерфейс программы пишется на GTK+ (остальное написано на с++ и всё вместе компилируется под Visual Studio 10). При запуске программы создаётся пара вычислительных потоков, потом при помощи GTK+ рисуется основное окно и управление передаётся gtk_main(). Поначалу отладочная информация вычислительных потоков выводилась в стандартную консоль Windows (всё работало стабильно), а потом захотелось вывести эти данные в основном окне (уменьшить количество окошек на экране). В результате в какой-нибудь момент работы программы выскакивает ошибка: «Нарушение прав доступа при чтении», или такая: «ОС Windows инициировала точку останова в <название программы>. Это может быть вызвано повреждением кучи и указывает на ошибку в …» (отключаю вывод данных в область вывода - всё работает стабильно).

Область вывода формируется вот так:


GtkWidget *textview_show( GtkWidget *box, char *tit, int len )

{

GtkWidget *list_view;

GtkTreeStore *store;

GtkTreeIter iter;

GtkCellRenderer *renderer;

GtkWidget* scroll;

GtkTreeViewColumn *column;



	scroll = gtk_scrolled_window_new (NULL, NULL);

    	gtk_container_set_border_width (GTK_CONTAINER (scroll), 10);    

       gtk_box_pack_start (GTK_BOX (box), scroll, TRUE, TRUE, 0);


       store = gtk_tree_store_new(1, G_TYPE_STRING);

	gtk_tree_store_append (store, &iter,NULL);

	gtk_tree_store_set (store, &iter, 0, win_to_utf_( "пам-па-бам", 256 ), -1);


	list_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));

	gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (list_view), TRUE);

	gtk_container_add(GTK_CONTAINER(scroll), list_view);


    	renderer = gtk_cell_renderer_text_new ();

	column = gtk_tree_view_column_new_with_attributes(win_to_utf_( "1", 256 ), renderer, "text", 0, NULL);

	gtk_tree_view_append_column(GTK_TREE_VIEW (list_view), column);


	gtk_widget_show_all(box);


	FILE *f=fopen( BCVM_FILE_LOG, "w" );

	fclose(f);


	return (GtkWidget *)list_view;

}


GtkWidget *_GLOBAL_TEXT;

void wmain1( int argc, char **argv )

{

…

_GLOBAL_TEXT = textview_show( hbox[3], "", len );

…

}

Выдача информации в область вывода происходит вот так:


void GTKConsole( char *sOutput )

{

GtkTreeModel *model;

GtkTreeIter   iter;

GtkAdjustment *vadj;

FILE *f;


static gint count=0;

static bool buzy=false;


	while(buzy){;;};

	buzy = true;


	if(_GLOBAL_TEXT){

		f=fopen( BCVM_FILE_LOG, "ab" );

		fprintf( f, "%s", sOutput );

		fclose(f);


		model=gtk_tree_view_get_model ((GtkTreeView *)_GLOBAL_TEXT);


		if(count>1000){

			gtk_tree_store_clear(GTK_TREE_STORE (model));

			count = 0;

		}

		count++;

	
		gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);

		gtk_tree_store_set (GTK_TREE_STORE (model), &iter, 0,  win_to_utf_( sOutput, 256 ), -1);


			
		vadj = gtk_scrollable_get_vadjustment ((GtkScrollable *)_GLOBAL_TEXT);

		gtk_adjustment_set_value(vadj, gtk_adjustment_get_upper(vadj));

				
	}


	buzy = false;

}

Вызов этой функции:


{

…

// вывод в стандартную консоль 

WriteConsole(hStdOutNew ,sOutput ,strlen(sOutput) ,NULL,NULL);	

// вывод в область вывода в окне

GTKConsole( str );

…

}


обращаться к GTK-функциям нужно из UI-потока, т.е. из того в котором запущен gtk_main.

чтобы это осуществить, нужно вынести код для обновления интерфейса в отдельную функцию, и вызывать ее через g_idle_add.

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

что-то вроде такого..

вызов GTKConsole из другого потока:

g_idle_add (GTKConsole, strdup (str));

и изменения GTKConsole:

gboolean GTKConsole(void *data)
{
 char *sOutput = data;
............
 free (sOutput);
 return FALSE;
}

и весь while (busy) мусор удалить.

waker ★★★★★ ()

Поскольку есть желание в будущем перейти на Linux, интерфейс программы пишется на GTK+ (остальное написано на с++ и всё вместе компилируется под Visual Studio 10)

Казалось бы, почему для такой задачи не взять более подходящий Qt?

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

XMs, я c GTK+ немного случайно знакома, и он мне в принципе понравился: можно ручками по кирпичикам всё сложить аккуратно - и должно заработать, можно легко включить в проект, и так же легко отключить при необходимости (это я с MFC-шными InitInstance-ами, реестром и другими «заморочками» сравниваю).

С QT планирую познакомиться, но пока ещё руки не дошли... Почему полагаете QT более подходящим?

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

Нормальная кроссплатформенность из коробки — раз. Изначальная ориентация на C++ — два. Куда более приятный API — три. Наличие плагина для студии, упрощающего некоторые вещи — четыре.

А вообще, этот вопрос способен породить некислый срач.

// И не QT, что есть QuickTime, а Qt (кьют)

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

А вообще, этот вопрос способен породить некислый срач.

Поробую:

Нормальная кроссплатформенность из коробки — раз.

Согласен — нормальная, не отличная. А по факту кроссплатформенность для гуи — это вегда компромис. Гуй нужно строить нативными инструментами, чтобы он не выглядел как уродец.
Qt — это монстр. Всегда поражаюсь, как Qt-шные пейсатели взгромождают его на android.

Изначальная ориентация на C++ — два.

Тут согласен. Аргумент.

Куда более приятный API — три.

Куда? Более приятный, чем Gtk? Это дело вкуса. По мне, так Qt менее приятный чем Gtk. Правда с доками у Qt лучше.

Наличие плагина для студии, упрощающего некоторые вещи — четыре.

Плагинами мериться — себя не уважать.

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

Всегда поражаюсь, как Qt-шные пейсатели взгромождают его на android.

2gis написан очень приятно, не ?

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

чтобы он не выглядел как уродец

QFormLayout, QDialogButtonBox и несколько других классов решат эту проблему хотя бы частично.


Более приятный, чем Gtk?

Да.


Это дело вкуса

Допустим (можно и возразить, но тогда точно будет пустой срач).


Плагинами мериться — себя не уважать

По мне так писать в студии — уже мазохизм

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

решат эту проблему хотя бы частично

Ну согласись, что гуи-кроссплатформеность, нужна только для больших проектов, у котрых на гуи реализована основная функциональность и нет ресурсов поддерживать разные платформы в разных ветках, например Gimp.
Как ни крути, а писать приходится под конкретную платформу, со своими дизайнами и особенностями взаимодействия. Для это лучше использовать нативные инструменты. В противном случае всегда приходится «решать проблему хотя бы частично».

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

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

Поясни, почему. На мой взгляд наоборот, GUI-кроссплатформенность нужна любому проекту, у которого есть GUI. В чём отличие, по большому счёту? Расположение кнопок в диалогах, выравнивание текста в формах, может, ещё организация меню. Что ещё?

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

В чём отличие, по большому счёту? Расположение кнопок в диалогах, выравнивание текста в формах, может, ещё организация меню. Что ещё?

Самая большая проблема, это сам Qt, это такой гипертрофированный переросток. Использование его на android'е — это просто катастрофа.

Расположение кнопок в диалогах, выравнивание текста в формах, может, ещё организация меню — это тоже немаловажная часть. Зоопарк тулкитов и движков в системе. wx, Qt, Gtk, Java, Blender и т.п. все организованы и выглядят по-разному. + потребление памяти разными тулкитами.

На разных десктопах разные возможности взаимодействия с самой системой - это тоже накладывает свой отпечаток.

Самый оптимальный вариант, это как делает transmission: ядро + интерфейс на выбор.

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

XMs, anonymous, большое спасибо за информацию!

Когда руки дойдут до знакомства с Qt - смогу выяснить собственные предпочтения :))

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

GUI-кроссплатформенность нужна любому проекту, у которого есть GUI

спорное утворждение, хотя хотелось бы конечно, чтобы было так. впрочем мечтать не вредно

чем конкретно плох Qt для этой цели, так это тем, что писатели приложений на Qt зачем то используют его не только для построения гуя, но и для написания всего приложения. таким образом все строковые значения становятся кьютэшными строками (не помню, как там тип называется, qstring что ли) вместо std::string, сетевая часть реализуется полностью на Qtшной сетевой библиотеке, и так далее. в результате ты открываешь исходники с желанием прикрутить к этому приложению нормальный гуй на GTK, смотришь на всё это безобразие, понимаешь что придётся переписать всё с нуля и закрываешь. вот за что я больше всего ненавижу Qt.

Выдохнул.

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

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

Я правильно понимаю, что все эти негуйные возможности Qt — это аналог GLib?

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

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

Потому что Qt для этого прекрасно подходит. Он предоставляет удобное кросплатформенное API для почти всех задачь.
Я как-то пытался использовать boost_filesystem вместо Qt - кошмар, больше так делать не буду. Разве что std::filesystem из C++17 потыкаю и мб буду иногда юзать.

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

открываешь исходники с желанием прикрутить к этому приложению нормальный гуй на GTK

вся суть тулкитофобства: вместо использования нормального готового решения вспыхивает NIH-синдром.

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

Использование его на android'е — это просто катастрофа

Не использовал, поэтому судить не могу.


Расположение кнопок в диалогах, выравнивание текста в формах, может, ещё организация меню — это тоже немаловажная часть

Вот это Qt берёт на себя при использовании указанных выше классов: оно подстраивается под системный стиль (примеры в документации для QDialogButtonBox и QFormLayout).


Самый оптимальный вариант, это как делает transmission: ядро + интерфейс на выбор

Да, тут соглашусь

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

> Куда более приятный API — три.
ложь

4.2. По сравнению в GTK и FLTK (с чем сталкивался) — API Qt просто божественный.


зачем то используют его не только для построения гуя, но и для написания всего приложения

Увы, но он более приятен даже в сравнении с STL

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

Да. И не только: сеть, базы данных, мультимедиа, с недавних пор ещё и 3D

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

Это Motif, Athena и OpenLook?

А какой из них используется в качестве нативного в Windows, в Эпловских осях, в андроидах, в KDE, в Gnome и тд?

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

Это нативные тулкиты в GNU/Linux.

Красавец! Это не ты случайно предлагал саблезубых тигров в красную книгу занести?

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

неправильно. это аналог большого множества библиотек на основе GObject, таких как gio, glib-networking, gdbus, и т.д.

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

я когда то давно пробовал изучать Qt, но увидев такие вещи, как signals, slots в объявлениях классов, несовместимые с алгоритмами из std:: контейнеры, строки и прочую лабуду, проблевался и пошёл изучать Gtkmm

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

несовместимые с алгоритмами из std:: контейнеры

Вообще у них там есть совместимость, по крайней мере сейчас

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

По сравнению в GTK и FLTK (с чем сталкивался) — API Qt просто божественный.

Про FLTK не скажу, но по сравнению с Qt, API Gtk просто божественный.

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

это да. но когда я пробовал изучать Qt, у меня ещё не вызывали. а потом я просто перешёл на биндинги Gtk к другим языкам. тут у Qt кстати тоже выбор не очень широкий...

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

Там часть страниц проектов 404. Байндинги к яве последний раз обновлялись в 2013 году, а Browse Source дает опять же 404.

Реально используемые и живые так же как и у Qt - кресты, питон. Яваскрипт еще, т.к. гном, но у кутей он есть свой.

В чем же получается отсталость?

Midael ★★★★★ ()
Последнее исправление: Midael (всего исправлений: 1)
Ответ на: комментарий от Midael

стандартный gir считай универсальный биндинг для всего. Плюс под тем же зонтиком он же стандартно покрывает дофига glib/gobject библиотек. А в Qtшых шаг в сторону от коробочного функционала уже проблемы.
Отмечаю все это как бывший фанат Qtей вплоть до 4-ки.

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