2016-04-28 14 views
6

Tôi đang cố gắng tìm ra cách để ứng dụng GTK tự động thoát sau một thời gian nhất định.Mã không thể thoát khỏi ứng dụng GTK - dường như không có vòng lặp tin nhắn

Vì vậy, tôi có một hàm callback mà có nghĩa là để tắt ứng dụng:

static gboolean killOffApp (gpointer userData) { 
    gtk_main_quit(); 
    return FALSE; 
} 

Sau đó, trong xử lý activate tín hiệu, tôi bắt đầu hẹn giờ năm giây:

static void activate (GtkApplication* app, gpointer user_data) { 
    GtkWidget *window = gtk_application_window_new (app); 
    g_timeout_add_seconds (5, killOffApp, NULL); 
    gtk_widget_show_all (window); 
} 

Và, để hoàn thành, dưới đây là main gắn bộ xử lý tín hiệu và chạy ứng dụng GTK:

int main (int argc, char **argv) { 
    GtkApplication *app = gtk_application_new ("com.example", G_APPLICATION_FLAGS_NONE); 
    g_signal_connect (app, "activate", G_CALLBACK (activate), NULL); 
    int status = g_application_run (G_APPLICATION (app), argc, argv); 
    g_object_unref (app); 
    return status; 
} 
.210

Vấn đề của tôi là, khi các đám cháy hẹn giờ, cuộc gọi đến gtk_main_quit dường như là không hợp lệ và tôi không chắc chắn lý do tại sao:

(MyProg:776): Gtk-CRITICAL **: gtk_main_quit: assertion 'main_loops != NULL' failed 

Tôi đã nghiên cứu vấn đề trên web nhưng chỉ tìm thấy những thứ mà hoặc:

  • nó được thực hiện từ một phần của mã nơi có một vòng lặp bên trong chạy (chẳng hạn như trong một hộp thoại) để nó tắt rằng một chứ không phải là vòng lặp chính (không phải là trường hợp ở đây, tôi tin) ; hoặc
  • không có vòng lặp chạy từ đó, ví dụ: ứng dụng được chạy với một ảnh gtk_main_iteration_do (Tôi cũng không nghĩ đó là trường hợp ở đây).

Tôi rõ ràng đang làm điều gì đó sai, tại sao ứng dụng của tôi dường như không có vòng lặp tin nhắn đang chạy?

Trả lời

5

Chức năng gtk_main_quit có vẻ không phù hợp khi sử dụng GtkApplication. Từ những người đã được tham gia vào sự phát triển của dự án GNOME khác nhau, một Emmanuele Bassi(a) nhận xét elsewhere (hơi diễn giải và lưu ý đặc biệt là đoạn thứ hai):

Nếu bạn đang gọi điện thoại g_application_run() sau đó bạn don cũng không cần phải gọi số gtk_main(): phương thức run() sẽ quay vòng chính cho bạn.

Bạn cũng không sử dụng gtk_main_quit() để ngừng vòng lặp chính của ứng dụng: bạn nên sử dụng g_application_quit() để thay thế.


Với ý nghĩ đó, bạn cần phải vượt qua các ứng dụng để gọi lại, và gọi việc áp dụng chức năng với nó bỏ:

static void activate (GtkApplication* app, gpointer user_data) { 
    GtkWidget *window = gtk_application_window_new (app); 
    g_timeout_add_seconds (forceShutdown, killOffApp, app); // << here 
    gtk_widget_show_all (window); 
} 

static gboolean killOffApp (gpointer userData) { 
    g_application_quit (userData); // << and here 
    return FALSE; 
} 

(a) Ai , theo ý kiến ​​của tôi, có cách ảnh quá tự mãn :-)

+0

Điều gì h appens nếu bạn gọi ['g_application_quit()'] (https://developer.gnome.org/gio/unstable/GApplication.html # g-application-quit) thay vì 'gtk_main_quit()' trong mã ban đầu của bạn? – andlabs

+0

@andlabs, hoạt động như vậy, khi tôi chuyển ứng dụng sang cuộc gọi lại. Sẽ cập nhật câu trả lời. – paxdiablo

+0

Điều đó có lẽ sẽ được ghi rõ ràng hơn; bạn có thể gửi một vấn đề trên bugzilla GNOME chính thức cho thấy tài liệu nói không gọi 'gtk_main_quit()' nếu bạn sử dụng GtkApplication ... – andlabs

Các vấn đề liên quan