2010-11-09 3 views
0

J'écris un cours qui peut prendre mes propres images RVB et les afficher dans Windows en utilisant GTK + -2.2. La classe My Image stocke les images en tant qu'octets RVB 24 bits compressés, donc la conversion doit être triviale. J'utilise la méthode gdk_draw_rgb (...) pour dessiner à ma fenêtre, mais rien ne se dessine du tout - la fenêtre apparaît juste en gris. J'ai réussi à utiliser Cairo, malheureusement, Cairo ne peut représenter que des images au format 32bpp, et faire cette conversion était trop lent.Affichage de l'image RVB dans GTK + -2.2

class ImageDisplay 
    { 
    public: 
     ImageDisplay(); 
     ~ImageDisplay(); 

     void showImage(Image img, std::string label=""); 

    private: 
     std::thread _gtkThread; 

     std::map<std::string, GtkWidget*> _windows; 
    }; 

// ###################################################################### 
void gtkThreadMethod() 
{ 
    g_thread_init(NULL); 
    gdk_threads_init(); 
    gdk_threads_enter(); 

    int argc=1; 
    char **argv = new char*; 
    argv[0] = new char[8]; 
    sprintf(argv[0], "display"); 
    gtk_init(&argc, &argv); 

    gdk_rgb_set_verbose(TRUE); 

    gtk_main(); 

    gdk_threads_leave(); 
} 

// ###################################################################### 
ImageDisplay::ImageDisplay() 
{ 
    // Start gtk in its own thread 
    _gtkThread = std::thread(gtkThreadMethod); 
} 

// ###################################################################### 
ImageDisplay::~ImageDisplay() 
{ 
    // Tell GTK that it's time to quit 
    gdk_threads_enter(); 
    gtk_main_quit(); 
    gdk_threads_leave(); 

    // Wait for the thread to die 
    _gtkThread.join(); 
} 

// ###################################################################### 
void ImageDisplay::showImage(Image img, std::string label) 
{ 
    gdk_threads_enter(); 

    // Create a new window if one doesn't yet exist 
    if(_windows.find(label) == _windows.end()) 
    { 
    GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 
    gtk_window_set_title(GTK_WINDOW(window), label.c_str()); 
    gtk_window_set_default_size(GTK_WINDOW(window), img.dims().w(), img.dims().h()); 
    gtk_widget_set_app_paintable(window, TRUE); 
    gtk_window_set_resizable(GTK_WINDOW(window), true); 
    GdkGeometry size_hints; 
    size_hints.min_aspect = 1; 
    size_hints.max_aspect = 1; 
    gtk_window_set_geometry_hints(GTK_WINDOW(window), window, 
     &size_hints, GDK_HINT_ASPECT); 
    gtk_widget_show_all(window); 
    _windows[label] = window; 
    } 

    GtkWidget* window = _windows[label]; 

    GdkGC *gc = gdk_gc_new(gtk_widget_get_root_window(window)); 
    gdk_draw_rgb_image(
     gtk_widget_get_root_window(window), 
     gc, 
     0, 0, 
     img.dims().w(), img.dims().h(), 
     GDK_RGB_DITHER_NORMAL, 
     (const unsigned char*)img.const_begin(), 
     img.dims().w()*3); 

    gdk_threads_leave(); 
} 
+1

et la question est? –

+0

"... mais rien ne se dessine du tout - la fenêtre apparaît juste grise." Donc je suppose que la question serait: "qu'est-ce que je fais mal?" – rcv

Répondre

1
gdk_draw_rgb_image(
    gtk_widget_get_root_window(window), 

Il y a votre problème. Dans la terminologie X (que GTK + emprunte fortement), la "fenêtre racine" fait référence à l'arrière-plan du bureau. Vous voulez gtk_widget_get_window qui vous obtiendra le GdkDrawable qui représente votre fenêtre.

Cependant ... je n'ai pas marché très loin de la pile à partir de la ligne ci-dessus, et je ne suis pas sûr de ce que l'appelant de ce code ressemble, mais vous voulez généralement dessiner dans un gestionnaire "event event" , plutôt que immédiatement après l'appel gtk_window_new. La dernière fois que j'écrivais ce type de code (cela fait un moment, je le reconnais), je créerais un GdkPixmap pour dessiner puis copier son contenu dans l'événement visible GdkWindow visible par l'utilisateur. Le widget GtkDrawingArea est utile ici, donc je chercherais des exemples en utilisant cela.

+0

Yup, le gtk_widget_get_root_window était le problème, merci beaucoup. C'est dommage que la documentation de Gtk soit si pauvre. – rcv

+0

@Boatzart - Je ne suis pas sûr que ce soit une question de mauvaise qualité dans ce cas, car cela suppose que vous connaissez la terminologie X. Vous pourriez prétendre que cela devrait vous faciliter la tâche, mais OTOH serait terriblement répétitif si chaque fois qu'une fenêtre racine était mentionnée, elle expliquait ce que c'était. – asveikau

+0

C'est toujours difficile d'équilibrer, mais la documentation de Qt penche beaucoup plus vers le côté convivial et par conséquent je trouve qu'il est beaucoup plus facile de travailler avec. – rcv

1

Pour afficher une image (côté client), je pense que vous devriez envisager d'utiliser le widget GtkImage, plutôt que de "surcharger" un widget aléatoire pour faire de la peinture personnalisée.

Ceci exposera à son tour un GdkPixbuf contenant les pixels.