2013-05-07 62 views
1

我是GTK +的新手。我想創建一個帶有2個按鈕的圖像和一個下面的標籤的GUI。 圖像必須通過一個文件對話框加載,當我點擊一個名爲「加載」的按鈕時打開該對話框,但圖像沒有顯示在窗口上。以下是我的代碼:gtk - 從文件加載時不顯示圖像

#include <gtk/gtk.h> 
#include <gtkmm.h> 
#include <glib.h> 
#include <cstring> 
#include <cstdlib> 

#include "cv.h" 
#include "opencv2/highgui/highgui.hpp" 
#include "opencv2/imgproc/imgproc.hpp" 

#include <iostream> 

using namespace std; 
using namespace cv; 

GtkWidget *window, *image; 
GtkWidget *vbox, *valign, *hbox, *halign; 
GtkWidget *expression_label; 

char* get_file() 
{ 
    GtkWidget *dialog = gtk_file_chooser_dialog_new("Open File", (GtkWindow *) window, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); 

    if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) 
    { 
     char *filename; 

     filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); 
     gtk_widget_destroy(dialog); 

     return filename; 
    } 

} 

void load_file(GtkWidget *widget, gpointer data) 
{ 
    g_print("Loading file\n"); 
    char *file = get_file(); 

    Mat img = imread(file); 
    //imshow("Opencv image", img); 

    image = gtk_image_new_from_file(file); 

    gtk_widget_queue_draw(image); 
    // gtk_box_pack_start(GTK_BOX(vbox), image, FALSE, FALSE, 0); 

    gtk_label_set_text(GTK_LABEL(expression_label), "Image Loaded");  
g_print("File Loaded\n"); 
g_print("%s\n", file); 

} 


void get_expression(GtkWidget *widget, gpointer data) 
{ 
    gtk_label_set_text(GTK_LABEL(expression_label), "Expression Detected"); 
} 


int main(int argc, char* argv[]) 
{ 

    gtk_init(&argc, &argv); 

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 

    gtk_window_set_title(GTK_WINDOW(window), "FEAR"); 
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); 
    gtk_window_set_default_size(GTK_WINDOW(window), 1100, 1100); 
    gtk_window_set_resizable(GTK_WINDOW(window), TRUE); 
    gtk_container_set_border_width(GTK_CONTAINER(window), 10); 

    vbox = gtk_vbox_new(FALSE, 5); 

    hbox = gtk_hbox_new(TRUE, 3); 

    GtkWidget *load_button = gtk_button_new_with_label("Load"); 
    GtkWidget *run_button = gtk_button_new_with_label("Run"); 
    gtk_widget_set_size_request(load_button, 70, 30); 
    gtk_widget_set_size_request(run_button, 70, 30); 

    gtk_container_add(GTK_CONTAINER(hbox), load_button); 
    gtk_container_add(GTK_CONTAINER(hbox), run_button); 

    expression_label = gtk_label_new("Expression"); 

    //image = gtk_image_new(); 

    //Display placeholder image  
    image = gtk_image_new_from_file("../sample.jpg"); 

    gtk_box_pack_start(GTK_BOX(vbox), image, FALSE, FALSE, 0); 
    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); 
    gtk_box_pack_start(GTK_BOX(vbox), expression_label, FALSE, FALSE, 0); 

    gtk_container_add(GTK_CONTAINER(window), vbox); 

    int load_handler_id = g_signal_connect(G_OBJECT(load_button), "clicked", G_CALLBACK(load_file), NULL); 

    g_signal_connect(G_OBJECT(run_button), "clicked", G_CALLBACK(get_expression), NULL); 


    g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); 

    gtk_widget_show_all(window); 

    gtk_main(); 


    return 0; 
} 

我基本上創建了一個主窗口,然後添加了一個vbox。在vbox中,我添加了圖像小部件,一個由按鈕和一個標籤小部件組成的hbox盒,以提供相關信息。

當我運行該程序時,它會正確顯示佔位符圖像,但是當我選擇「加載」並選擇要顯示的新圖像時,標籤會更改,並且我會在命令行上得到正確的輸出,但圖像小部件不顯示所選的新圖像。

有人可以幫助我,讓我知道我做錯了什麼?

回答

2

加載後,您將獲得一個新的GtkImage小部件,並且該小部件永遠不會添加到窗口中,因此當然不會顯示它。

您只是用新小部件覆蓋全局小部件指針,但這並不奇怪地使新小部件「替換」小部件層次結構中的舊部件。從GTK +的角度來看,用於存放舊部件的變量中存儲指向新部件的指針並不重要。

與調用替換您到gtk_image_new_from_file()呼叫gtk_image_set_from_file()在你現有的小部件(在image),以取代現有的小部件,它包裝等,從文件的圖像內容。

另外,您正在泄漏文件名,您需要在使用後添加free()

UPDATE:您在評論中提到您已使文件名成爲全局文件名,以使其在更多位置可用。如果是這樣,你還需要free()舊的文件名才能得到一個新的,否則你的代碼將泄漏內存。

+0

哦,非常感謝!我昨天剛剛開始使用GTK,但仍未完全確定它的工作方式,但這清除了很多事情。真的很棒的答案。 另外,我需要使用文件名來調用一些OpenCV代碼,所以我決定讓它成爲一個全局字符指針。 再次,非常感謝。 :) – varagrawal 2013-05-07 19:48:18