Gtk3和cairo g#u timeout#u add不';行不通
我用gtk3和cairo制作了非常简单的动画。我得到了Gtk3和cairo g#u timeout#u add不';行不通,c,gtk3,cairo,C,Gtk3,Cairo,我用gtk3和cairo制作了非常简单的动画。我得到了g\u timeout\u add,它应该每隔1ms调用draw函数,但是它调用draw的速度要慢得多。为什么会发生这种情况,我该如何解决 #include <gtk/gtk.h> #include <cairo.h> gboolean timeout(GtkWidget *widget) { gtk_widget_queue_draw(widget); return TRUE; } void dr
g\u timeout\u add
,它应该每隔1ms调用draw
函数,但是它调用draw
的速度要慢得多。为什么会发生这种情况,我该如何解决
#include <gtk/gtk.h>
#include <cairo.h>
gboolean timeout(GtkWidget *widget)
{
gtk_widget_queue_draw(widget);
return TRUE;
}
void draw(GtkWidget* widget, cairo_t* cr)
{
static int width, height,
posX = 0,
vX = 1;
GtkWidget* window = gtk_widget_get_toplevel(widget);
gtk_window_get_size(GTK_WINDOW(window), &width, &height);
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_set_line_width(cr, 1);
cairo_rectangle(cr, posX, height/2, 1, 1);
cairo_stroke(cr);
if(posX + vX >= width || posX + vX == 0)
vX = -vX;
posX += vX;
}
int main(int argc, char** argv)
{
GtkWidget* window;
GtkWidget* darea;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
darea = gtk_drawing_area_new();
gtk_container_add(GTK_CONTAINER(window), darea);
gtk_window_set_default_size(GTK_WINDOW(window), 500, 400);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(G_OBJECT(darea), "draw", G_CALLBACK(draw), NULL);
g_timeout_add(1, (GSourceFunc)timeout, window);
gtk_widget_show_all(window);
gtk_main();
}
#包括
#包括
gboolean超时(GtkWidget*小部件)
{
gtk_小部件_队列_绘制(小部件);
返回TRUE;
}
无效绘制(GtkWidget*小部件,cairo_t*cr)
{
静态整数宽度,高度,
posX=0,
vX=1;
GtkWidget*窗口=gtk_小部件_获取_顶层(小部件);
gtk_窗尺寸(gtk_窗(窗)、宽度和高度);
cairo\u set\u source\u rgb(cr,0,0,0);
cairo_集_线_宽(cr,1);
cairo_矩形(cr,posX,高度/2,1,1);
脑卒中(cr);
如果(posX+vX>=宽度| | posX+vX==0)
vX=-vX;
posX+=vX;
}
int main(int argc,字符**argv)
{
GtkWidget*窗口;
GtkWidget*darea;
gtk_init(&argc,&argv);
窗口=gtk_窗口_新建(gtk_窗口_顶层);
darea=gtk_图纸_区域_新();
gtk_容器添加(gtk_容器(窗口),darea);
gtk_窗口设置默认大小(gtk_窗口(窗口),500,400);
g_信号连接(g_对象(窗口),“销毁”,g_回调(gtk_主退出),NULL);
g_信号连接(g_对象(darea),“绘制”,g_回调(绘制),空);
g_timeout_add(1,(GSourceFunc)超时,窗口);
gtk_小部件_全部显示(窗口);
gtk_main();
}
根据GLib关于g\u timeout\u add()的文档
:
由于事件循环正在为您的应用程序执行其他操作(包括运行
draw()
函数),因此超时可能无法跟上1ms的节拍,当然不应该依赖它来精确计时。根据GLib的g\u timeout\u add()文档:
因为事件循环正在为您的应用程序执行其他操作(包括运行draw()
函数),所以超时可能无法跟上1ms的节拍,当然不应该依赖它来精确计时
为什么会发生,以及
Zrax对此作出了回答。我只想添加一些东西:我在draw函数中添加了以下内容(并添加了相应的include)
我得到如下输出:
1518869317.202412
1518869317.218970
1518869317.236563
1518869317.253032
1518869317.269721
1518869317.286305
因此,draw函数大约每17毫秒调用一次,或每秒调用60次
我怎样才能修好它
#include <gtk/gtk.h>
#include <cairo.h>
gboolean timeout(GtkWidget *widget)
{
gtk_widget_queue_draw(widget);
return TRUE;
}
void draw(GtkWidget* widget, cairo_t* cr)
{
static int width, height,
posX = 0,
vX = 1;
GtkWidget* window = gtk_widget_get_toplevel(widget);
gtk_window_get_size(GTK_WINDOW(window), &width, &height);
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_set_line_width(cr, 1);
cairo_rectangle(cr, posX, height/2, 1, 1);
cairo_stroke(cr);
if(posX + vX >= width || posX + vX == 0)
vX = -vX;
posX += vX;
}
int main(int argc, char** argv)
{
GtkWidget* window;
GtkWidget* darea;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
darea = gtk_drawing_area_new();
gtk_container_add(GTK_CONTAINER(window), darea);
gtk_window_set_default_size(GTK_WINDOW(window), 500, 400);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(G_OBJECT(darea), "draw", G_CALLBACK(draw), NULL);
g_timeout_add(1, (GSourceFunc)timeout, window);
gtk_widget_show_all(window);
gtk_main();
}
这就提出了一个问题:你为什么要画的速度超过60帧
如何创建一个GTimer
并使用g\u timer\u appeased()
来确定必须在哪里绘制?也就是说,不要假设您绘制的速度足够快,而是在每次绘制时计算当前图形状态
为什么会发生,以及
Zrax对此作出了回答。我只想添加一些东西:我在draw函数中添加了以下内容(并添加了相应的include)
我得到如下输出:
1518869317.202412
1518869317.218970
1518869317.236563
1518869317.253032
1518869317.269721
1518869317.286305
因此,draw函数大约每17毫秒调用一次,或每秒调用60次
我怎样才能修好它
#include <gtk/gtk.h>
#include <cairo.h>
gboolean timeout(GtkWidget *widget)
{
gtk_widget_queue_draw(widget);
return TRUE;
}
void draw(GtkWidget* widget, cairo_t* cr)
{
static int width, height,
posX = 0,
vX = 1;
GtkWidget* window = gtk_widget_get_toplevel(widget);
gtk_window_get_size(GTK_WINDOW(window), &width, &height);
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_set_line_width(cr, 1);
cairo_rectangle(cr, posX, height/2, 1, 1);
cairo_stroke(cr);
if(posX + vX >= width || posX + vX == 0)
vX = -vX;
posX += vX;
}
int main(int argc, char** argv)
{
GtkWidget* window;
GtkWidget* darea;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
darea = gtk_drawing_area_new();
gtk_container_add(GTK_CONTAINER(window), darea);
gtk_window_set_default_size(GTK_WINDOW(window), 500, 400);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(G_OBJECT(darea), "draw", G_CALLBACK(draw), NULL);
g_timeout_add(1, (GSourceFunc)timeout, window);
gtk_widget_show_all(window);
gtk_main();
}
这就提出了一个问题:你为什么要画的速度超过60帧
如何创建一个GTimer
并使用g\u timer\u appeased()
来确定必须在哪里绘制?也就是说,不必假设您的绘图速度足够快,您只需在每次绘图时计算当前图形状态。但它的工作速度要慢得多,不会延迟1毫秒或5毫秒,至少慢50倍。这是不正常的。但它的工作速度要慢得多,它不会延迟1毫秒或5毫秒,至少慢50倍。这不正常。非常感谢你,现在我明白了!非常感谢,现在我明白了!