2010-11-09 2 views
0

Я пишу класс, который может принимать мои собственные изображения RGB и отображать их в окнах с помощью GTK + -2.2. Класс My Image сохраняет изображения как упакованные 24-битные байты RGB, поэтому преобразование должно быть тривиальным. Я использую метод gdk_draw_rgb (...) для рисования в моем окне, но ничего не получается вообще - окно просто отображается серым.Отображение изображения RGB в GTK + -2.2

Я получил это, чтобы работать с использованием Каира, к сожалению, Каир может представлять только изображения в формате 32bpp, и это преобразование было слишком медленным.

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

и вопрос есть? –

+0

«... но ничего не нарисовано вообще - окно просто выглядит серым». Поэтому я предполагаю, что вопрос будет следующим: «Что я делаю неправильно?» – rcv

ответ

1
gdk_draw_rgb_image(
    gtk_widget_get_root_window(window), 

Там ваша проблема. В X-терминологии (которую GTK + занимает значительно), «корневое окно» относится к фону рабочего стола. Вы хотите gtk_widget_get_window, который доставит вам GdkDrawable, который представляет ваш окно.

Однако ... Я не очень сильно прошел по стеку из строки выше, и я не уверен, как выглядит вызывающий код этого кода, но вы обычно хотите использовать обработчик «выставить событие» , а не сразу после звонка gtk_window_new. В прошлый раз, когда я писал такой код (я бы это признал давно), я бы сделал, чтобы создать GdkPixmap для рисования, а затем скопировать его содержимое в видимый пользователем GdkWindow на событие экспонирования. Виджет GtkDrawingArea полезен здесь, поэтому я бы поискал примеры, используя это.

+0

Yup, проблема с gtk_widget_get_root_window, спасибо вам большое. Слишком плохо, что документация Gtk настолько бедна. – rcv

+0

@Boatzart - Я не уверен, что дело в том, что оно плохое в этом случае, так как предполагает, что вы знаете X-терминологию. Вы можете утверждать, что это должно облегчить вам эту терминологию, но OTOH было бы ужасно повторяющимся, если бы каждый раз, когда упоминалось корневое окно, оно объясняло, что это такое. – asveikau

+0

Всегда сложно балансировать, но документация Qt опирается гораздо дальше на удобную для пользователя сторону, и в результате мне гораздо легче работать. – rcv

1

Чтобы отобразить (на стороне клиента) изображение, я думаю, вы должны изучить виджет GtkImage, а не «перегрузку» случайного виджета, чтобы сделать обычную картину.

Это, в свою очередь, выставляет GdkPixbuf, удерживая пиксели.

Смежные вопросы