GtkDrawingArea не будет обновляться при рисовании, если используется Glade - PullRequest
0 голосов
/ 24 ноября 2018

Я создал очень простое приложение GTK3 C с поляной, которое содержит кнопку и GtkDrawingArea (хранится вместе с GtkPaned).Когда кнопка нажата, она должна сразу нарисовать прямоугольник, однако этого не происходит.Это происходит только тогда, когда мышка воет на GtkPaned разделенную часть (см. .Gif).Если Glade не используется, то такой проблемы не существует.

Как решить эту проблему?

A simple .gif gif

C code:

#include <gtk/gtk.h>

//==============================================================Global=variables========================================================================
static cairo_surface_t *surface = NULL;
GtkWidget *DrawArea;

//==============================================================Functions===============================================================================


void clear_surface (void)
{
    cairo_t *cr;

    cr = cairo_create (surface);

    cairo_set_source_rgb (cr, 0, 1, 1);
    cairo_paint (cr);

    cairo_destroy (cr);
}

//Create a new surface of the appropriate size to store our scribbles
gboolean configure_event_cb (GtkWidget *widget, GdkEventConfigure *event, gpointer data)
{
    if (surface)
    {
        cairo_surface_destroy (surface);
    }


    surface = gdk_window_create_similar_surface (gtk_widget_get_window (widget), CAIRO_CONTENT_COLOR, gtk_widget_get_allocated_width (widget), gtk_widget_get_allocated_height (widget));

    /* Initialize the surface to white */
    clear_surface ();

    /* We've handled the configure event, no need for further processing. */
    return TRUE;
}

/* Redraw the screen from the surface. Note that the ::draw
 * signal receives a ready-to-be-used cairo_t that is already
 * clipped to only draw the exposed areas of the widget
 */
gboolean draw_cb (GtkWidget *widget, cairo_t *cr, gpointer data)
{
    cairo_set_source_surface (cr, surface, 0, 0);
    cairo_paint (cr);

    return FALSE;
}

//Draw a rectangle on the surface at the given position
void draw_brush (GtkWidget *widget, double x, double y)
{
    cairo_t *cr;

    /* Paint to the surface, where we store our state */
    cr = cairo_create (surface);

    cairo_rectangle (cr, x - 3, y - 3, 6, 6);
    cairo_fill (cr);

    cairo_destroy (cr);

    //Now invalidate the affected region of the drawing area.
    gtk_widget_queue_draw_area (widget, x - 3, y - 3, 6, 6);
}

void draw_rectangle (GtkWidget *widget, float posX, float posY, float length, float height, float colorR, float colorG, float colorB)
{
    cairo_t *cr;

    /* Paint to the surface, where we store our state */
    cr = cairo_create (surface);
    cairo_set_source_rgb (cr, colorR, colorG, colorB);

    cairo_rectangle (cr, posX, posY, length, height);
    cairo_fill (cr);

    cairo_destroy (cr);

    //Now invalidate the affected region of the drawing area.
    gtk_widget_queue_draw_area (widget, posX, posY, length, height);
}


//==================================Button=stuff==========================
void Button_clicked(GtkWidget* widget, gpointer data)
{
    g_print("Clicked\n");
    draw_brush (DrawArea, 10, 10);
    //gtk_widget_queue_draw (window_main);
}





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


    GtkBuilder      *builder; 
    GtkWidget       *window;

    gtk_init(&argc, &argv);

    DrawArea = gtk_drawing_area_new ();
    builder = gtk_builder_new();
    gtk_builder_add_from_file (builder, "Resources/GUI_design.glade", NULL);

    window = GTK_WIDGET(gtk_builder_get_object(builder, "window_main"));
    gtk_builder_connect_signals(builder, NULL);

    g_object_unref(builder);

    gtk_widget_show(window);                
    gtk_main();

    return 0;
}




// called when window is closed
void on_window_main_destroy()
{
    gtk_main_quit();
}

Код поляны:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
  <requires lib="gtk+" version="3.20"/>
  <object class="GtkWindow" id="window_main">
    <property name="can_focus">False</property>
    <property name="default_width">500</property>
    <property name="default_height">500</property>
    <property name="icon">icon.png</property>
    <signal name="destroy" handler="on_window_main_destroy" swapped="no"/>
    <child type="titlebar">
      <placeholder/>
    </child>
    <child>
      <object class="GtkPaned" id="paned">
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="orientation">vertical</property>
        <property name="position">300</property>
        <property name="position_set">True</property>
        <child>
          <object class="GtkDrawingArea" id="DrawArea">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <signal name="configure-event" handler="configure_event_cb" swapped="no"/>
            <signal name="draw" handler="draw_cb" swapped="no"/>
          </object>
          <packing>
            <property name="resize">False</property>
            <property name="shrink">False</property>
          </packing>
        </child>
        <child>
          <object class="GtkButton" id="Button">
            <property name="label" translatable="yes">button</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
            <signal name="clicked" handler="Button_clicked" swapped="no"/>
          </object>
          <packing>
            <property name="resize">True</property>
            <property name="shrink">True</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

1 Ответ

0 голосов
/ 25 ноября 2018

Я наконец нашел и исправил проблему !!!!

int main теперь выглядит следующим образом (удалена 1 строка и добавлена ​​1 строка)

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


    GtkBuilder      *builder; 
    GtkWidget       *window;

    gtk_init(&argc, &argv);

    //DrawArea = gtk_drawing_area_new ();
    builder = gtk_builder_new();
    gtk_builder_add_from_file (builder, "Resources/GUI_design.glade", NULL);

    window = GTK_WIDGET(gtk_builder_get_object(builder, "window_main"));
    gtk_builder_connect_signals(builder, NULL);

    DrawArea = GTK_WIDGET(gtk_builder_get_object(builder, "DrawArea")); //This is very important

    g_object_unref(builder);

    gtk_widget_show(window);                
    gtk_main();

    return 0;
}

Описание причины этой проблемы:Глейд и я создали 2 отдельных указателя, и я делал вещи только с указателем, а не с Глейдом.Эта важная строка соединяет эти два указателя, и теперь это работает.Джуху!

Этот урок помог мне решить проблему: https://prognotes.net/2016/03/gtk-3-c-code-hello-world-tutorial-using-glade-3/

...