gtk定时器的使用

⌚Time: 2022-07-14 20:47:31

👨‍💻Author: Jack Ge

GTK定时器可以周期性执行任务,并且使用简单。定时器是图形界面程序中不可缺少的工具,比多线程可靠和安全。GTK像MFC和QT一样都有定时器

gtk定时器:


guint g_timeout_add(guint interval, GSourceFunc function, gpointer data);



interval:设置的时间间隔,以毫秒为单位( 1000即为1秒 )

function:回调函数的名字

data:给回调函数传的参数

返回值:定时器id号

定时器的移除:


gboolean g_source_remove(guint tag);



tag:定时器id号

返回值:TRUE代表成功,FALSE代表失败

对于定时器运行的函数,返回false则定时器只运行一次,而返回true,定时器会重复运行

例子




guint id = g_timeout_add(1000,(GSourceFunc)(function),NULL);

下面是使用criao绘图库配合定时器简单的趣味动态绘制线条:

效果

代码


#include <gtk/gtk.h>
#include <stdio.h>
//time()
#include <time.h>
//rand()
#include <stdlib.h>

#define X_WIDTH 600
#define X_HEIGHT 400
#define POINT_NUM 6
guint timer_0,timer_1;
typedef struct _POINT{
        gint x;
        gint y;
}Point;
Point points[POINT_NUM];
void init_points(){
        srand((unsigned int)time(0));
        for(int i = 0;i<POINT_NUM;i++){
            points[i].x = rand()%X_WIDTH;
            points[i].y = rand()%X_HEIGHT;
        }
}
gboolean move_point(GtkWidget *widget){
    for(int i = 0;i<POINT_NUM;i++){
        points[i].x += rand()%2?1:-1;
        points[i].y += rand()%2?1:-1;
        if(points[i].x >X_WIDTH){
            points[i].x = X_WIDTH;
        }
        if(points[i].x <0){
            points[i].x = 0;
        }
        if(points[i].y >X_HEIGHT){
            points[i].y = X_HEIGHT;
        }
        if(points[i].y <0){
            points[i].y = 0;
        }
    }
    return true;
}

gboolean show_graph(GtkWidget *widget){
            
    cairo_t *cr;
    cr = gdk_cairo_create (widget->window);
    
    cairo_set_source_rgb(cr,0,0,0);
    cairo_move_to(cr,0, 0);
    cairo_line_to(cr,X_WIDTH,0);
    cairo_line_to(cr,X_WIDTH,X_HEIGHT);
    cairo_line_to(cr,0,X_HEIGHT);
    //cairo_stroke_preserve绘图后会保留路径,之后cairo_fill可以填充。而cairo_stroke绘图后不会保留路径,cairo_fill就无法填充
    cairo_stroke_preserve(cr);
    cairo_fill(cr);
    
    srand((unsigned int)time(0));
    for(int i = 0;i<POINT_NUM;i++){
        for(int j=i+1;j<POINT_NUM;j++){
            cairo_set_source_rgb(cr,0.39,1,1);
            cairo_set_line_width(cr,1);
            cairo_move_to(cr,points[i].x, points[i].y);
            cairo_line_to(cr,points[j].x, points[j].y); 
            cairo_stroke(cr);//clear line path
        }
   }
   /*
    cairo_destroy (cr);
        while(g_main_context_pending(NULL)){
        g_main_context_iteration(NULL,false);
    }
    */
    return true;
}
int main(int argc,char* argv[]){


    GtkWidget *window;
    gtk_init(&argc,&argv);
 
    window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window),"Demo");
    gtk_window_set_default_size(GTK_WINDOW(window),X_WIDTH,X_HEIGHT);

    g_signal_connect(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),NULL);
    //启动定时器
    timer_0 = g_timeout_add(30,(GSourceFunc)move_point,window);
    timer_1 = g_timeout_add(30,(GSourceFunc)show_graph,window);

    gtk_widget_show_all(window);
    init_points();
    //设置窗口可绘制
    gtk_widget_set_app_paintable(window,true);
    gtk_main();
 
    return 0;
}