开罗和GTK +,未知的抽奖活动和节目停止

时间:2015-12-08 15:30:02

标签: c linux gtk cairo

我正在与Cairo和GTK3.0合作,我遇到的问题我不知道如何解决。

目前我有2个奇怪的东西,我不知道要解决。

  1. 只要终端浮动在绘图窗口上,就会调用draw事件。
  2. 该程序不会通过gtk_main();功能
  3. 我将在下面提供我的代码,这是非常基本的,它基于:http://zetcode.com/gfx/cairo/cairobackends/,GTK窗口部分。 我最终只需要一个窗口,我可以在我的代码中随时调用draw事件。

    #include <cairo.h>
    #include <gtk/gtk.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct {
        int xStart;
        int yStart;
        int xEnd;
        int yEnd;
    } lineData;
    
    int i = 0;
    int gonnaDraw = 0;
    lineData *lines;
    int lineSize = 0;
    
    /**
     * The drawing with the cairo elements is done here.
     * The new line is saved to an array. 
     * Eventually there should be a loop that draws all lines in the array.
     */
    static void do_drawing(cairo_t *cr) {
        printf("I'm endless, somehow.\n");
        if(lineSize != 0) { //We only want to draw in the infinite for loop, not before it.
            cairo_set_source_rgb(cr, 255, 0, 0);
            cairo_set_line_width(cr, 1.0);
    
            lineData newLine = { 10.0 + i, 50.0 + i, 100.0 + i, 50.0 + i };
    
            //lines[lineSize - 1] = newLine;
    
            cairo_move_to(cr, newLine.xStart, newLine.xEnd);
            cairo_line_to(cr, newLine.yStart, newLine.yEnd);
    
            cairo_stroke(cr);
    
            i = i + 10;
            printf("i: %d\n", i);
            gonnaDraw = 1;
        }
    }
    
    static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, gpointer user_data) {
        do_drawing(cr);
    
        return FALSE;
    }
    
    int main (int argc, char *argv[]) {
        GtkWidget *window;
        GtkWidget *darea;
        printf("1\n");
        gtk_init(&argc, &argv);
        printf("2\n");
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        printf("3\n");
        darea = gtk_drawing_area_new();
        printf("4\n");
        gtk_container_add(GTK_CONTAINER(window), darea);
        printf("5\n");
        g_signal_connect(G_OBJECT(darea), "draw", G_CALLBACK(on_draw_event), NULL);
        g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
        printf("6\n");
        gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
        gtk_window_set_default_size(GTK_WINDOW(window), 800, 800);
        gtk_window_set_title(GTK_WINDOW(window), "GTK window");
        printf("7\n");
        gtk_widget_show_all(window);
        printf("8\n");
        gtk_main(); // If I'm removed I got no drawing window.
        printf("9\n"); // I do not show up.
        lines = (lineData *) malloc(lineSize * sizeof(lineData));
    
        for(;;) {
            if(gonnaDraw == 1) {
                lineSize++;
                printf("lineSize: %d\n", lineSize);
                lines = (lineData *) realloc(lines, lineSize * sizeof(lineData));
                gtk_widget_queue_draw(window);
                gonnaDraw = 0;
            }
        }
    
        return 0;
    }
    

    用标准方法编译。

1 个答案:

答案 0 :(得分:1)

您现在几乎了解GTK +绘图模型。问题1是它的结果:当另一个窗口超过你的时候,窗口系统告诉GTK +该区域需要重新绘制。当我谈到裁剪时,这就是我的意思 现在另一部分是了解GTK +事件模型。所有窗口系统都以这样的方式运行:所有程序在程序处于活动状态时由组成的循环上运行,从窗口系统获取消息并对其进行操作。这就是gtk_main()的作用。 gtk_main()没有归还是正常的;在调用gtk_main_quit()之前它不会返回。除了使用信号在小部件交互时执行操作时,有两种方法可以“挂钩”主循环:g_timeout_add(),它按计划运行功能,g_idle_add(),它运行下一次可能的功能。如果你想要经常发生的事情,前者是有用的;如果您希望工作线程通知UI更新,则后者非常有用。主循环上的GLib文档将告诉您更多信息。我仍然不确定你的最终目标是什么,所以我想你可以尝试两者同时看看会发生什么   - andlabs