gtk - 从文件加载时未显示图像

时间:2013-05-07 13:07:08

标签: c++ gtk

我是GTK +的新手。我想创建一个带有2个按钮的图像的GUI和下面的标签。 必须通过文件对话框加载图像,当我单击一个名为“加载”的按钮时,该对话框会打开,但图像不会显示在窗口上。以下是我的代码:

#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框和一个标签小部件,以便为我提供相关信息。

当我运行程序时,它会正确显示占位符图像,但是当我选择“加载”并选择要显示的新图像时,标签会更改,我会在命令行上获得正确的输出,但是图像小部件不显示所选的新图像。

有人可以帮助我,让我知道我做错了什么?

1 个答案:

答案 0 :(得分:2)

加载后你会得到一个新的GtkImage小部件,并且该小部件永远不会添加到窗口中,因此(当然)它没有被显示。

您只是使用新窗口小部件覆盖全局窗口小部件指针,但这并不会神奇地使新窗口小部件“替换”窗口小部件层次结构中的旧窗口小部件。在GTK +的角度来看,将指针存储在用于保存旧小部件的变量中的新小部件并不重要。

通过调用现有小部件(gtk_image_new_from_file())中的gtk_image_set_from_file()替换您对image的通话,以替换现有小部件的内容, 打包等等,带有文件中的图像。

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

更新:您在评论中提到您已将文件名设为全局,以使其在更多位置可用。如果是这样,您在获取新文件名之前仍需要free() 文件名,否则您的代码将泄漏内存。