GUI で、ユーザーが GtkEntry に挿入したテキストを変更したいと考えています。たとえば、ユーザーが「joHn doe」と入力すると、GUI はこれが適切にフォーマットされた名前ではないことを認識し、これを「John Doe」に変更します。
たとえばGtkEntry text change signalで説明されているように、ハンドラを「changed」シグナルに接続します。発生する問題は、シグナル ハンドラーのエントリを変更すると、王国が来るまで「変更された」シグナルが何度も発行されることです。
私は現在、文字列比較を行うことでこれを防いでおり、「名前付き」バージョンのテキストがエントリ内のテキストと等しくない場合にのみ、GtkEntryBuffer 内のテキストを変更します。ただし、プログラマーとして、変更されたハンドラーが何度も呼び出されることなく、エントリ内のテキストを変更できるはずだと感じています。
変更されたシグナル ハンドラーは次のとおりです。
void nameify_entry ( GtkEditable* editable, gpointer data )
{
gchar* nameified;
const gchar *entry_text;
entry_text = gtk_entry_get_text( GTK_ENTRY(editable) );
nameified = nameify(entry_text);
/*is it possible to change the buffer without this using this string
comparison, without the "change" signal being emitted over and over again?*/
if ( g_strcmp0(entry_text, nameified) != 0 ){
GtkEntryBuffer* buf = gtk_entry_get_buffer(GTK_ENTRY(editable) );
gtk_entry_buffer_set_text( buf, nameified, -1 );
}
g_free(nameified);
}
私のnameify関数は次のとおりです。
/*removes characters that should not belong to a name*/
gchar*
nameify ( const char* cstr )
{
const char* c;
gchar* ret_val;
GString* s = g_string_new("");
gboolean uppercase_next = TRUE;
g_debug( "string = %s", cstr);
for ( c = cstr; *c != '0'; c = g_utf8_next_char(c) ) {
gunichar cp = g_utf8_get_char(c);
if ( cp == 0 ) break;
if ( g_unichar_isalpha( cp ) ){
if ( uppercase_next ){
g_string_append_unichar( s, g_unichar_toupper(cp) );
uppercase_next = FALSE;
}
else{
g_string_append_unichar(s,g_unichar_tolower(cp));
}
}
if ( cp == '-' ){
g_string_append_unichar( s, cp);
uppercase_next = TRUE;
}
if ( cp == ' '){
g_string_append_unichar( s, cp);
uppercase_next = TRUE;
}
}
ret_val = s->str;
g_string_free(s, FALSE);
return ret_val;
}
どんな助けでも大歓迎です。