gtk_widget_show_all (окно);не работает при ожидании функции, возвращающей значение - PullRequest
0 голосов
/ 09 декабря 2018

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

Я делаюмакет, вызовите gtk_widget_show_all (window) ;, затем вызовите await_dart_hit ();

Окно не отображается, пока дротик не попадет.Как будто окно не может отображаться, пока не завершится вся функция, но я попытался создать окно в отдельной функции, затем вернуть, затем вызвать await_dart_hit ();и это тоже не работает.

#include <gtk/gtk.h>

void problem_causing_wait(){
    while(1);
}

void start(){
    GtkWidget *window;

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window),"Start");
    gtk_container_set_border_width(GTK_CONTAINER(window),10);
    gtk_window_set_default_size(GTK_WINDOW(window),1000,400);

    gtk_widget_show_all(window);

    problem_causing_wait();
}

int main(int argc, char *argv[]) {
    GtkWidget *window, *button, *button_box;

    gtk_init(&argc,&argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window),"Welcome!");
    gtk_window_set_default_size(GTK_WINDOW(window),1000,400);

    button_box = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
    gtk_container_add(GTK_CONTAINER(window),button_box);

    button = gtk_button_new_with_label("Get Started");
    g_signal_connect (button, "clicked", G_CALLBACK (start), NULL);
    g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);
    gtk_container_add(GTK_CONTAINER(button_box),button);

    gtk_widget_show_all(window);

    gtk_main();

    return(0);
}

Если вы запустите этот код, вы увидите, что как только вы нажмете кнопку «Начать», он зависнет.Он не отображает окно «Пуск», несмотря на то, что показывает все перед вызовом функции problem_causing_wait ().

Пожалуйста, помогите!

скомпилировано с: gcc main.c -o main pkg-config --cflags --libs gtk+-3.0

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

Вы не должны заморозить пользовательский интерфейс.Замораживание пользовательского интерфейса означает отсутствие обновления, даже если обновление требуется.Например, если вы переместите другое приложение на передний план, а затем переместите его, ваше приложение все равно придется перекрасить.Вы также не можете показать обратный отсчет оставшегося времени для стрельбы из дротика.Из-за этого вы не можете обрабатывать случаи, когда игрок полностью не попадает в цель (здесь вы, вероятно, должны либо взаимодействовать с пользовательским интерфейсом, либо позволить обратному отсчету хода закончиться с некоторой обратной связью).

Вместо этого не надовообще используйте потоки и используйте g_timeout_add, чтобы каждые 500 мс проверять, попал ли дротик на игровое поле, позволяя основному циклу GTK + обрабатывать опрос вашего ввода / вывода.

0 голосов
/ 10 декабря 2018

Поскольку ваше приложение выполняется в одном потоке, эта функция "problem_causing_wait" действует как блокирующая функция и останавливает основной цикл.

Я думаю, использование "g_idle_add" и "g_thread_new" может решить вашу проблему.

    #include <gtk/gtk.h>

void *problem_causing_wait(){
    while(1);
    //update the Ui using g_idle_add
    return NULL;
}

void start(){
    GtkWidget *window;

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window),"Start");
    gtk_container_set_border_width(GTK_CONTAINER(window),10);
    gtk_window_set_default_size(GTK_WINDOW(window),1000,400);

    g_thread_new("dart-game",problem_causing_wait,NULL);

    gtk_widget_show_all(window);
}

int main(int argc, char *argv[]) {
    GtkWidget *window, *button, *button_box;

        //Initilizes Support for Concurrent Threads
    XInitThreads();

    gtk_init(&argc,&argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window),"Welcome!");
    gtk_window_set_default_size(GTK_WINDOW(window),1000,400);

    button_box = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
    gtk_container_add(GTK_CONTAINER(window),button_box);

    button = gtk_button_new_with_label("Get Started");
    g_signal_connect (button, "clicked", G_CALLBACK (start), NULL);
    //g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);
    gtk_container_add(GTK_CONTAINER(button_box),button);

    gtk_widget_show_all(window);

    gtk_main();

    return(0);
} 
...