c - update - python gtk




MessageBox의 GTK 구현 (2)

GTK를 사용하여 Win32의 MessageBox 를 구현하려고했습니다. SDL / OpenGL을 사용하는 앱이므로 GTK 앱이 아닙니다.

MessageBox 함수 내에서 다음과 같이 초기화 ( gtk_init ) 정렬을 처리합니다.

int MessageBox(HWND hwnd, const char* text, const char* caption, UINT type)
{
    GtkWidget *window = NULL;
    GtkWidget *dialog = NULL;

    gtk_init(&gtkArgc, &gtkArgv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), NULL);
    g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL);
    // gcallback calls gtk_main_quit()
    gtk_init_add((GtkFunction)gcallback, NULL);

    if (type & MB_YESNO) {
        dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, text);
    } else {
        dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, text);
    }

    gtk_window_set_title(GTK_WINDOW(dialog), caption);
    gint result = gtk_dialog_run(GTK_DIALOG(dialog));

    gtk_main();

    gtk_widget_destroy(dialog);

    if (type & MB_YESNO) {
        switch (result) {
        default:
        case GTK_RESPONSE_DELETE_EVENT:
        case GTK_RESPONSE_NO:
            return IDNO;
            break;
        case GTK_RESPONSE_YES:
            return IDYES;
            break;
        }
    }

    return IDOK;
} 

지금, 나는 결코 경험있는 GTK 프로그래머가 아니며, 나는 아마도 끔찍한 잘못을 저 지르고 있음을 알고 있습니다.

그러나, 내 문제는이 함수를 사용하여 마지막으로 대화 상자를 팝업 프로세스가 종료 될 때까지 주위에 남아 있습니다. 어떤 아이디어?


몇 가지:

window라는 이름의 불필요한 최상위 창을 만들고 window . 다음 행을 삭제하면됩니다.

window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), NULL);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL);

또한 흐름이 옳지 않은 것처럼 보입니다. gtk_main() 은 GTK 메인 루프를 시작한다. gtk_dialog_run() 은 또한 메인 루프를 시작하지만 버튼 중 하나를 클릭하자마자 종료됩니다.

gtk_init_add()gtk_main() 호출을 제거하고 리턴 값을 처리하기 만하면됩니다. 또한 gtk_dialog_run ()이 반환 될 때 다이얼로그 창이 자동으로 소멸되므로 gtk_widget_destroy() 호출은 불필요합니다.


음 알았어. 다음과 같은 코드를 제안합니다.

typedef struct {
    int type;
    int result;
} DialogData;

static gboolean
display_dialog(gpointer user_data)
{
    DialogData *dialog_data = user_data;
    GtkWidget *dialog;

    if (dialog_data->type & MB_YESNO)
        dialog = gtk_message_dialog_new(...);
    else
        dialog = gtk_message_dialog_new(...);

    // Set title, etc.

    dialog_data->result = gtk_dialog_run(...);

    gtk_main_quit();  // Quits the main loop run in MessageBox()

    return FALSE;
}

int MessageBox(...)
{
    DialogData dialog_data;

    dialog_data.type = type;

    gtk_idle_add(display_dialog, &dialog_data);

    gtk_main();

    // Do stuff based on dialog_data.result
}

구조체는 두 개의 데이터 조각을 전달해야하기 때문에 발생합니다. gtk_idle_add() 호출은 메인 루프가 실행 중이고 유휴 상태 일 때 실행될 메소드를 추가하고 display_dialog() 호출의 FALSE 리턴 값은 그것이 한 번만 실행된다는 것을 의미합니다. 대화 상자에서 결과를 얻은 후 주 루프를 종료합니다. 그러면 주 MessageBox() 메서드의 gtk_main() 이 반환되고 거기에서 결과에 액세스 할 수 있습니다.

희망이 도움이!







x11