Blog (9)
Komentarze (7)
Recenzje (0)

Prosta nakładka graficzna na eSpeak w GTK+

@skrzeczol755Prosta nakładka graficzna na eSpeak w GTK+10.07.2012 18:55

Czas na powrót do GTK… Jak zaznaczono w tytule, zajmiemy się GTK+, a nie GTKmm, czyli napiszemy program w C.

Jeżeli zajmujemy się tworzeniem za pomocą Anjuta, wybieramy zakładkę „C” i typ projektu „GTK+ (prosty)” przy tworzeniu nowego projektu i zostawiamy domyślne ustawienia, ale jeśli chodzi o nazwę projektu oraz podstawowe informacje o autorze, wpisujemy, co nam będzie pasować.

Zaznaczenie opcji (ptaszek lub inny znaczek) „Użycie biblioteki GtkBuilder dla interfejsu użytkownika” jest kluczowe, gdyż to nam umożliwi wykorzystanie gotowego interfejsu programu dla tych, którzy woleliby to napisać w czymś innym niż C.

Interfejs użytkownika

Użyjemy dwóch pudełek (ang. Box): jedno jako zawartość okna, drugie jako zawartość górnej komórki tego pierwszego. Pierwsze ma orientację poziomą (domyślną), drugie pionową. W lewej komórce będzie etykieta tekstowa, w drugiej pole wejścia tekstowego.

Druga komórka najbardziej zewnętrznego pudełka będzie zawierać ramkę (z tytułem) Wewnątrz umieszczamy Przewijane okno, a wewnątrz niego wieloliniowe pole textowe (Text View).

Trzecia komórka najbardziej zewnętrznego pudełka będzie zawierać przycisk (Button). Podepniemy do niego funkcję pozwalającą na obsługę kliknięcia.

W panelu „Widżety” (Widgets) odnajdujemy zakładkę Sygnały (Signals). W rozwijanej liście odnajdujemy GtkButton i pozycję „clicked”. Klikamy w tym wierszu na kolumnę „Program obsługujący i wpisujemy nazwę funkcji. We wszystkich nakładkach na GTK obsługujących automatyczne łączenie sygnałów nazwa funkcji będzie niezależna od użytego języka programowania.

W naszym przypadku zaczynamy od wpisywania „on”. Wyświetli się podpowiedź, co do nazwy tej funkcji. Zatwierdzamy ją. Nazwa sygnału zostanie pogrubiona dla wyróżnienia. Zapisujemy zmiany i mamy gotowy plik interfejsu.

Całość wygląda tak:

Gotowy interfejs naszej nakładku
Gotowy interfejs naszej nakładku

Kod

Automatycznie nam się wygeneruje import widżetu okna z pliku interfejsu, włączenie obsługi GTK, obsługa zdarzenia zamykania okna (powiązanie z nim zakończenia działania programu), pusta struktura _Private, odpowiednie stałe i włączone nagłówki.

Na początku użyjemy polecenia system() z biblioteki standardowej C, które umożliwi nam wykonywanie poleceń systemowych. Polecenie to staje się dostępne po włączeniu nagłówka stdlib.h. Możemy również wykorzystać inne polecenia do tworzenia procesów, ale o tym w innym wpisie.

Struktura _Private

Wewnątrz struktury _Private zadeklarujemy widżety GtkTextView i GtkEntry. Do tego między klamrą zamykającą strukturę a średnikiem wpiszemy nazwę struktury — dzięki temu struktura będzie zadeklarowana. Wszystkie pozostałe związane z tą strukturą rzeczy zostawiamy bez zmian. Struktura ta po zmianach jest taka:


static struct _Private
{
	/* ANJUTA: Widgets declaration for simple_espeak_gui.ui - DO NOT REMOVE */
	GtkTextView* users_text_to_speech;
	GtkEntry* lang_code;
} Widgets;

Import widżetów

Po zadeklarowaniu struktury zajmiemy się obsługą importu widżetów z pliku interfejsu. Sam kod będzie opierać się o domyślnie wygenerowany fragment dotyczący importu okna, przy założeniu, że Window jest typu wskaźnikowego GtkWidget:


window = GTK_WIDGET (gtk_builder_get_object (builder, TOP_WINDOW));
        if (!window)
        {
                g_critical ("Widget \"%s\" is missing in file %s.",
				TOP_WINDOW,
				UI_FILE);
        }

A teraz importujemy dwa najważniejsze widżety:


Widgets.input_text_to_speech = GTK_TEXT_VIEW (gtk_builder_get_object (builder, TTS));
if (!Struct.input_text_to_speech)
        {
                g_critical ("Widget \"%s\" is missing in file %s.",
				TTS,
				UI_FILE);
        }

Widgets.language = GTK_ENTRY (gtk_builder_get_object (builder, LANG));
if (!Struct.language)
        {
                g_critical ("Widget \"%s\" is missing in file %s.",
				LANG,
				UI_FILE);
        }

Mając w użyciu GtkBuider do importu widżetów z plików *.ui, importujemy widżety o określonych nazwach (najlepiej stałych, dlatego definiujemy sobie stałe. Tutaj została użyta dyrektywa #define na początku kodu źródłowego. Robi się to tak:

#define YOUR_TEXT "This is my text"

Tutaj zostało zrobione to tak:


#define LANG "langcode"
#define TTS "text-to-speech"

Aby import zadziałał, nazwy w stałych muszą się zgadzać z tymi przyporządkowanymi widżetom w pliku interfejsu.

Kod ten wstawiamy wewnątrz funkcji create_window(void) pod oznaczoną linijką komentarza:

ANJUTA: Widgets initialization for simple_espeak_gui.ui - DO NOT REMOVE

Dotyczy to tylko tworzenia z użyciem Anjuta IDE. Jeśli używamy czegoś innego, np. zestawu edytor tekstu (osobno) + kompilator (ręcznie obsługiwany) + projektant interfejsu (osobno), tworzymy całą funkcję (dostępną w kodzie referencyjnym, do którego link zostanie podany).

Zamieniamy tekst na mowę

Zakładam, że w pliku interfejsu zdefiniowaliśmy nazwę funkcji, która ma obsłużyć kliknięcie na przycisk. W tym przypadku nie trzeba definiować połączeń funkcji z sygnałami, gdyż zostaną wygenerowane automatycznie. Do tego nie importujemy przycisku, bo argumentem funkcji jest sam przycisk.

Oto kod, dzięki któremu zamienimy tekst na mowę:


GtkTextIter begin; //Beginning. NOTE: not a pointer
	GtkTextIter	end; // End. NOTE: not a pointer
	GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(Struct.input_text_to_speech));
	
	gtk_text_buffer_get_start_iter (buffer, &begin); //initialize start point
	gtk_text_buffer_get_end_iter (buffer, &end); //initialize end point

	//get text to be read by eSpeak
	const gchar* text_to_speech = gtk_text_buffer_get_text (GTK_TEXT_BUFFER(buffer), &begin, &end, FALSE);

	//get language code
	const gchar* language_code = gtk_entry_get_text(Struct.language);

	//composing a command;
	const gchar* command = g_strdup_printf("espeak \"%s\" -v %s", text_to_speech, language_code);
	
	//command to run espeak
	system(command);

Najpierw tworzymy dwie zmienne typu GtkTextIter, które będą wskazywać początek i koniec tekstu. Następnie deklarujemy bufor tekstowy i inicjalizujemy go buforem tekstu z dużego pola tekstowego. I zajmujemy się ustaleniem początku i końca tekstu przez funkcje gtk_text_buffer_get_start_iter (GtkTextBuffer*, GtkTextIter*) oraz gtk_text_buffer_get_start_iter (GtkTextBuffer*, GtkTextIter*).

Mając te dane pobierzemy do stałej tablicy znaków (const gchar*) zawartość widoku tekstowego za pomocą funkcji gtk_text_buffer_get_text(GtkTextBuffer*, GtkTextIter*, GtkTextIter*, gboolean). Pobierzemy również kod języka (niezbędny do ustalenia języka, w jakim będzie mówić eSpeak.

Napis o określonym formacie utworzymy za pomocą funkcji g_strdup_printf(const gchar*, ...) podobnie, jak to się robi przy wyświetlaniu tekstu za pomocą printf(const char*,...). Zadziała to tak, jak znane z Javy czy C# tworzenie napisu o określonym formacie.

Mając tak przygotowane polecenie (espeak "tu twój tekst" -v jezyk), mamy już sposób na wykorzystanie eSpeaka. Teraz ta zmienna, w której jest ono przechowywane, będzie argumentem polecenia system(const char*) i za jego pomocą przeczytamy tekst wprowadzony przez użytkownika.

Kompilacja i uruchomienie

Jeśli chodzi o zależności kompilacyjne, powinny wystarczyć te, które muszą zostać spełnione, aby prosty program w GTK+ mógł zostać skompilowany i działać prawidłowo. Po uruchomieniu program będzie wyglądać tak:

Program w działaniu
Program w działaniu

Kod referencyjny jest dostępny tu.

Podsumowanie

Co prawda już istnieją takie nakładki, ale nie zaszkodzi napisać własnej :) Możemy wtedy uwzględnić opcje, jakich potrzebujemy, a autorzy istniejących nie przewidzieli. Następne wpisy z tej tematyki będą omawiać ulepszenia tej oto nakładki.

Szanowna Użytkowniczko! Szanowny Użytkowniku!
×
Aby dalej móc dostarczać coraz lepsze materiały redakcyjne i udostępniać coraz lepsze usługi, potrzebujemy zgody na dopasowanie treści marketingowych do Twojego zachowania. Twoje dane są u nas bezpieczne, a zgodę możesz wycofać w każdej chwili na podstronie polityka prywatności.

Kliknij "PRZECHODZĘ DO SERWISU" lub na symbol "X" w górnym rogu tej planszy, jeżeli zgadzasz się na przetwarzanie przez Wirtualną Polskę i naszych Zaufanych Partnerów Twoich danych osobowych, zbieranych w ramach korzystania przez Ciebie z usług, portali i serwisów internetowych Wirtualnej Polski (w tym danych zapisywanych w plikach cookies) w celach marketingowych realizowanych na zlecenie naszych Zaufanych Partnerów. Jeśli nie zgadzasz się na przetwarzanie Twoich danych osobowych skorzystaj z ustawień w polityce prywatności. Zgoda jest dobrowolna i możesz ją w dowolnym momencie wycofać zmieniając ustawienia w polityce prywatności (w której znajdziesz odpowiedzi na wszystkie pytania związane z przetwarzaniem Twoich danych osobowych).

Od 25 maja 2018 roku obowiązuje Rozporządzenie Parlamentu Europejskiego i Rady (UE) 2016/679 (określane jako "RODO"). W związku z tym chcielibyśmy poinformować o przetwarzaniu Twoich danych oraz zasadach, na jakich odbywa się to po dniu 25 maja 2018 roku.

Kto będzie administratorem Twoich danych?

Administratorami Twoich danych będzie Wirtualna Polska Media Spółka Akcyjna z siedzibą w Warszawie, oraz pozostałe spółki z grupy Wirtualna Polska, jak również nasi Zaufani Partnerzy, z którymi stale współpracujemy. Szczegółowe informacje dotyczące administratorów znajdują się w polityce prywatności.

O jakich danych mówimy?

Chodzi o dane osobowe, które są zbierane w ramach korzystania przez Ciebie z naszych usług, portali i serwisów internetowych udostępnianych przez Wirtualną Polskę, w tym zapisywanych w plikach cookies, które są instalowane na naszych stronach przez Wirtualną Polskę oraz naszych Zaufanych Partnerów.

Dlaczego chcemy przetwarzać Twoje dane?

Przetwarzamy je dostarczać coraz lepsze materiały redakcyjne, dopasować ich tematykę do Twoich zainteresowań, tworzyć portale i serwisy internetowe, z których będziesz korzystać z przyjemnością, zapewniać większe bezpieczeństwo usług, udoskonalać nasze usługi i maksymalnie dopasować je do Twoich zainteresowań, pokazywać reklamy dopasowane do Twoich potrzeb. Szczegółowe informacje dotyczące celów przetwarzania Twoich danych znajdują się w polityce prywatności.

Komu możemy przekazać dane?

Twoje dane możemy przekazywać podmiotom przetwarzającym je na nasze zlecenie oraz podmiotom uprawnionym do uzyskania danych na podstawie obowiązującego prawa – oczywiście tylko, gdy wystąpią z żądaniem w oparciu o stosowną podstawę prawną.

Jakie masz prawa w stosunku do Twoich danych?

Masz prawo żądania dostępu, sprostowania, usunięcia lub ograniczenia przetwarzania danych. Możesz wycofać zgodę na przetwarzanie, zgłosić sprzeciw oraz skorzystać z innych praw wymienionych szczegółowo w polityce prywatności.

Jakie są podstawy prawne przetwarzania Twoich danych?

Podstawą prawną przetwarzania Twoich danych w celu świadczenia usług jest niezbędność do wykonania umów o ich świadczenie (tymi umowami są zazwyczaj regulaminy). Podstawą prawną przetwarzania danych w celu pomiarów statystycznych i marketingu własnego administratorów jest tzw. uzasadniony interes administratora. Przetwarzanie Twoich danych w celach marketingowych realizowanych przez Wirtualną Polskę na zlecenie Zaufanych Partnerów i bezpośrednio przez Zaufanych Partnerów będzie odbywać się na podstawie Twojej dobrowolnej zgody.