2017-12-01 1 views
2

시간을 표시하는 응용 프로그램을 만들고 싶습니다 (궁극적으로 기존 스마트 미러 API를 사용하지 않고 간단한 스마트 미러를 해킹하려고합니다). UI 용 GTK3을 사용하고 있지만 UI 업데이트를 할 수있는 솔루션을 찾는 데 어려움을 겪고 있습니다 (프론트 엔드 나 GTK에서 경험하지 못했습니다).GTK의 인터페이스 업데이트

아래 보이는 view3 코드의 일부분에 루프를 배치 해 보았습니다 만, 일단 gtk_main()이 호출되면 gtk 기본 루프에서 빠져 나올 수 없으므로 while 루프가 시작되고 시간이 회수됩니다. 나는 썼다.

gtk_main_iteration_do (gtk_false()) (false가 차단되지 않도록)와 같은 함수를 사용해 보았지만 작동하지 않기 때문에이 함수에 대해 충분히 이해하지 못했습니다. gtk_main()을 루프 밖으로두면 분명히 gtk_main()이 호출되지 않고 응용 프로그램 창이 열리지 않습니다.

필자가 작성한 get_time_string() 함수의 정의와 관련하여 아래에 main에 관련 코드가 표시되어 있습니다. get_time_string의

int 
main (int argc, 
     char *argv[]) 
{ 
    // initialization and setting up window, packing widgets, etc 

    // view3 
    // populate buffer with time string 
    // and insert into text view 
    view3 = gtk_text_view_new(); 
    gtk_widget_set_name(view3, "view3"); 
    buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view3)); 
    gtk_text_buffer_get_iter_at_offset(buffer, &iter, 0); 
    gtk_text_buffer_insert(buffer, &iter, get_time_string(), -1); 
    gtk_text_view_set_editable(GTK_TEXT_VIEW(view3), FALSE); 
    gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(view3), FALSE); 


    // More widget packing, setting up UI 

    gtk_widget_show_all(window); 

    gtk_main(); 

    return 0; 
} 

정의()

char* get_time_string(){ 
    time_t time_var = time(NULL); 
    struct tm *info; 
    char *time_string = calloc(100, sizeof(char)); 
    info = localtime(&time_var); 
    strftime(time_string, 100, "%I:%M %p", info); 
    return time_string; 
} 

답변

1

당신은 당신이 정말로 필요로하지 않는 돌이 반복하여 재생하거나 무엇을 해야할지하지 않아야합니다.

트릭은 g_timeout_add 또는 g_idle_add와 그 변형을 사용하는 것입니다. 일정한 간격으로 업데이트하는 시간을 원하면 (분당 60 초마다 업데이트됩니다) g_timeout_add_seconds를 사용할 수 있습니다.

#include <time.h> 
#include <stdlib.h> 
#include <gtk/gtk.h> 

char* get_time_string(){ 
    time_t time_var = time(NULL); 
    struct tm *info; 
    char *time_string = calloc(100, sizeof(char)); 
    info = localtime(&time_var); 
    strftime(time_string, 100, "%I:%M:%S %p", info); 
    return time_string; 
} 

gboolean update_label_time (gpointer user_data) { 
    gchar *t = get_time_string(); 
    gtk_label_set_text(GTK_LABEL(user_data), t); 
    g_free (t); 
    return G_SOURCE_CONTINUE; 
} 

int main (int argc, char *argv[]) 
{ 
    gchar *t; 
    GtkWidget *window; 
    GtkWidget *label_time; 

    gtk_init(&argc, &argv); 

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 
    gtk_window_set_default_size (GTK_WINDOW(window), 300, 200); 
    t = get_time_string(); 
    label_time = gtk_label_new (t); 
    g_free (t); 

    g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); 
    gtk_container_add (GTK_CONTAINER(window), label_time); 


    g_timeout_add_seconds(0.5, update_label_time, label_time); 


    gtk_widget_show_all(window); 

    gtk_main(); 

    return 0; 
} 

결과해야한다 : 그림의 목적

, 난 그냥 시간 레이블을 표시하는 매우 간단한 창을 귀하의 get_time_string 기능을 사용하지만, 생성, 시간 문자열에 초를 추가하고 매초마다 업데이트됩니다 레이블이 매 초마다 업데이트와 함께 창을 수 :

enter image description here

입심 당신이 사용해야하는 time functions 자신이있다.

+0

Hey José, 당신은'get_time_string'에 할당 된 문자열의 메모리를 누출하고 있습니다. 또 다른 문제는'g_timeout_add_seconds'가 실제로 정확하지 않고 문서에''타이머의 첫 번째 호출이 1 초의 타임 아웃에 대해 정확하지 않을 수 있음을 명심하십시오 '입니다. 그래서 500ms 샘플링을 가진'g_timeout_add'는 같은 시간이 2 초 동안 표시되지 않도록해야합니다. – liberforce

+0

@libforce 당신이 옳다, 나쁘다. 의견을 보내 주셔서 감사합니다. 모두 제일 좋다! –

+1

de nada, tenhaum bom dia;) – liberforce