C GtkDrawingArea赢得';如果使用Glade,则在绘制时不会更新

C GtkDrawingArea赢得';如果使用Glade,则在绘制时不会更新,c,gtk3,glade,C,Gtk3,Glade,我用glade创建了非常简单的GTK3 C应用程序,其中包含button和GtkDrawingArea(与GtkPaned结合在一起)。当按钮出现时,它应该立即绘制一个矩形,然而,它不会出现。只有当鼠标在GtkPaned split part(参见.gif)上移动时,才会发生这种情况。如果不使用Glade,那么这个问题就不存在了 如何解决这个问题 gif C代码: #include <gtk/gtk.h> //===================================

我用glade创建了非常简单的GTK3 C应用程序,其中包含button和GtkDrawingArea(与GtkPaned结合在一起)。当按钮出现时,它应该立即绘制一个矩形,然而,它不会出现。只有当鼠标在GtkPaned split part(参见.gif)上移动时,才会发生这种情况。如果不使用Glade,那么这个问题就不存在了

如何解决这个问题

gif

C代码:

#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();
}
#包括
//=================================================================================================全局=变量========================================================================
静态cairo_surface_t*surface=NULL;
GtkWidget*绘图区;
//==========================================================================================功能===============================================================================
空隙清除曲面(空隙)
{
开罗*cr;
cr=cairo_创建(曲面);
cairo\u set\u source\u rgb(cr,0,1,1);
开罗漆(cr);
开罗大学(cr);
}
//创建一个大小合适的新曲面来存储我们的涂鸦
gboolean配置事件cb(GtkWidget*小部件、GdkEventConfigure*事件、gpointer数据)
{
如果(表面)
{
开罗·表面·破坏(表面);
}
surface=gdk_window_create_simular_surface(gtk_widget_get_window(widget)、CAIRO_CONTENT_COLOR、gtk_widget_get_allocated_width(widget)、gtk_widget_get_allocated_height(widget));
/*将曲面初始化为白色*/
清除表面();
/*我们已处理配置事件,无需进一步处理*/
返回TRUE;
}
/*从表面重新绘制屏幕。注意::draw
*信号接收一个已准备好使用的CAROU\t
*剪裁为仅绘制小部件的暴露区域
*/
gboolean draw_cb(GtkWidget*小部件、cairo_t*cr、gpointer数据)
{
cairo_集_源_曲面(cr,曲面,0,0);
开罗漆(cr);
返回FALSE;
}
//在给定位置的曲面上绘制一个矩形
无效画笔(GtkWidget*小部件,双x,双y)
{
开罗*cr;
/*在我们存储状态的表面上涂漆*/
cr=cairo_创建(曲面);
cairo_矩形(cr,x-3,y-3,6,6);
开罗填料(cr);
开罗大学(cr);
//现在使绘图区域的受影响区域无效。
gtk_小部件_队列_绘图区(小部件,x-3,y-3,6,6);
}
void draw_矩形(GtkWidget*小部件、float posX、float posY、float length、float height、float colorR、float colorG、float colorB)
{
开罗*cr;
/*在我们存储状态的表面上涂漆*/
cr=cairo_创建(曲面);
cairo\u set\u source\u rgb(cr、color、colorG、colorB);
cairo_矩形(cr、posX、posY、长度、高度);
开罗填料(cr);
开罗大学(cr);
//现在使绘图区域的受影响区域无效。
gtk_小部件_队列_绘图_区域(小部件、posX、posY、长度、高度);
}
//===================================================按钮=东西==========================
单击无效按钮(GtkWidget*小部件,gpointer数据)
{
g_打印(“单击的\n”);
画笔(画笔区域,10,10);
//gtk_小部件_队列_绘制(窗口_主窗口);
}
int main(int argc,char*argv[])
{
GtkBuilder*builder;
GtkWidget*窗口;
gtk_init(&argc,&argv);
DrawArea=gtk_drawing_area_new();
builder=gtk_builder_new();
gtk_builder_从_文件添加_(builder,“Resources/GUI_design.glade”,NULL);
窗口=GTK_小部件(GTK_生成器_获取_对象(生成器,“窗口主”);
gtk_builder_connect_信号(builder,NULL);
g_object_unref(建筑商);
gtk_widget_show(窗口);
gtk_main();
返回0;
}
//窗口关闭时调用
窗口上的无效\u主\u销毁()
{
gtk_main_quit();
}
Glade代码:

<?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>

假的
500
500
icon.png
真的
真的
垂直的
300
真的
真的
假的
假的
假的
按钮
真的
真的
真的
真的
真的

我终于找到并解决了问题

int main现在看起来像这样(删除了一行,添加了一行)

说明导致此问题的原因:Glade和我创建了两个单独的指针,我只使用我的指针,而不是Glade的。这条重要的线连接了这两个指针,现在它工作了。朱


这个教程帮助我解决了这个问题:

我终于找到并解决了这个问题

int main现在看起来像这样(删除了一行,添加了一行)

说明导致此问题的原因:Glade和我创建了两个单独的指针,我只使用我的指针,而不是Glade的。这条重要的线连接了这两个指针,现在它工作了。朱

这个教程帮助我解决了这个问题:

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;
}