LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
12
返回列表 发新帖
楼主: Chowroc

在一个Gtk/Gnome的窗口中显示动态的数据?

[复制链接]
发表于 2004-8-2 12:12:04 | 显示全部楼层
如果你在工程的选项中选则了"设置构件名称",你就可以用
lookup_widge获得子构件的指针

  1. GtkWidget*  lookup_widget   (GtkWidget       *widget,
  2.                                               const gchar     *widget_name);
复制代码
发表于 2004-8-2 12:15:46 | 显示全部楼层
看看你的源码中应该有个自动生成的support.h
有这个函数的声明,用法
GtkWidget* b1 =  lookup_widget (GTK_WIDGET(window), "button1");
 楼主| 发表于 2004-8-2 12:28:14 | 显示全部楼层
非常感谢
 楼主| 发表于 2004-8-2 19:26:13 | 显示全部楼层
写一个如下的测试程序,我发现可以正确的从管道中读取数据。

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <sys/wait.h>
  6. #include <unistd.h>
  7. #include <fcntl.h>
  8. #include <errno.h>

  9. int main(int argc, char *argv[])
  10. {
  11.     char *fifo = "./fifo";
  12.     char buff[64] = "\0";
  13.     int ffd;

  14.     if((ffd = open(fifo, O_RDONLY | O_NONBLOCK)) < 0)  {
  15.         fprintf(stderr, "can't open fifo: %s\n", strerror(errno));
  16.         exit(1);
  17.     }

  18.     while(1)  {
  19.         read(ffd, buff, 64);
  20.         printf("gui: %s\n", buff);
  21.         sleep(1);
  22.      }

  23.     close(ffd);
  24. }
复制代码

但现在换成GTK中的Timeouts或上面的程序,在编译时得到如下警告:

  1.     // gtk_idle_add(read_fifo, NULL);
  2.     // gdk_input_add(fd, GDK_INPUT_READ, read_fifo, NULL);
  3.     gtk_timeout_add(1000, read_fifo, NULL);

  4. warning: passing arg 2 of `gtk_timeout_add' from incompatible pointer type
复制代码

忽略后执行程序,发现不能独到数据。是不是read_fifo要加一个转换宏呢?比如,在gtk_signal_connect中要用GTK_SIGNAL_FUNC(callback_func)。
 楼主| 发表于 2004-8-2 22:52:13 | 显示全部楼层
我最后使用了系统的定时器,关于定时的问题暂时解决了。但又遇到了一个奇怪的问题,看如下的代码:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <unistd.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>
  7. #include <gtk/gtk.h>
  8. #include <signal.h>
  9. #include <sys/time.h>

  10. #include <errno.h>
  11. #include <string.h>

  12. #include "support.h"

  13. #define POINT_NUM 20

  14. static int ffd;
  15. GtkWidget *GUI;

  16. void flush(char buf[])  {
  17.     static int hour, min, second;
  18.     static gfloat vin[POINT_NUM], vout[POINT_NUM];
  19.     int i;
  20.     GtkWidget *widget;
  21.     // char tstr[15] = "\0";
  22.     // char str[20] = "Time:";

  23.     sscanf(buf, "%d:%d:%d[6%lf:6%lf]", &hour, &min, &second, &vin[0], &vout[0]);
  24.     printf("gui2: %s: %d, %d, %d, %f, %f\n", buf, hour, min, second, vin[0], vout[0]);
  25.     for(i = 1; i < POINT_NUM; i++)  {
  26.         vin[i + 1] = vin[i];
  27.         vout[i + 1] = vout[i];
  28.     }
  29.     // strcpy(str, tstr);
  30.     widget = lookup_widget(GUI, "curve1");
  31.     gtk_curve_set_vector(GTK_CURVE(widget), POINT_NUM, vin);
  32.     widget = lookup_widget(GUI, "curve2");
  33.     gtk_curve_set_vector(GTK_CURVE(widget), POINT_NUM, vout);
  34.     widget = lookup_widget(GUI, "label3");
  35.     // gtk_label_set_text(GTK_LABEL(widget), str);
  36. }

  37. int open_fifo()  {
  38.     char *fifo = "./fifo";

  39.     if((ffd = open(fifo, O_RDONLY | O_NONBLOCK)) < 0)  {
  40.         fprintf(stderr, "can't open fifo: %s\n", strerror(errno));
  41.         // exit(1);
  42.         return -1;
  43.     }
  44.     return ffd;
  45. }

  46. gint read_fifo(gpointer data)  {
  47. // void read_fifo(gpointer data, gint fd, GdkInputCondition cond)  {
  48.     char buff[64] = "\0";

  49.     // GtkWidget *gui = (GtkWidget *)data;

  50.     read(ffd, buff, 64);
  51.     flush(buff);
  52.     printf("gui: %s\n", buff);

  53.     return 0;
  54. }

  55. void handle_timer(int sign)  {
  56.     if(sign == SIGALRM)  {
  57.         read_fifo(NULL);
  58.     }
  59. }

  60. void start_timer()  {
  61.     struct itimerval tv;

  62.     tv.it_value.tv_sec = 2; /* give 2 seconds for safety */
  63.     tv.it_value.tv_usec = 0;
  64.     tv.it_interval.tv_sec = 3;
  65.     tv.it_interval.tv_usec = 0;
  66.     signal(SIGALRM, handle_timer);
  67.     setitimer(ITIMER_REAL, &tv, NULL);
  68. }

  69. void stop_timer()  {
  70.     struct itimerval tv;

  71.     signal(SIGALRM, SIG_IGN);
  72.     tv.it_value.tv_sec = 0;
  73.     tv.it_value.tv_usec = 0;
  74.     tv.it_interval.tv_sec = 0;
  75.     tv.it_interval.tv_usec = 0;
  76.     setitimer(ITIMER_REAL, &tv, NULL);
  77. }
复制代码

在主函数中,先调用定时器,然后运行gtk_main(),在上面的程序中,如果把read_fifo()中的flush语句注释掉,则它下面的printf语句打印了正确的数据,但如果使用flush函数,则其中的printf语句不能打印正确结果,而前面那个printf打印出空结果。为什么是这样?
我把定时器的值增大,问题依旧。
 楼主| 发表于 2004-8-3 00:35:48 | 显示全部楼层
弄明白了,是循环用错了,应该是:
for(i = POINT_NUM - 2; i > 0; i--)  {...}
但为什么打印语句会受到影像呢,按道理来说,应该只是curve不能正确显示呀?
发表于 2004-8-3 08:38:56 | 显示全部楼层

  1. gint gtk_timeout_add( guint32     interval,
  2.                       GtkFunction function,
  3.                       gpointer    data );

  4. The declaration of your callback should look something like this:

  5. gint timeout_callback( gpointer data );
复制代码

warning: passing arg 2 of `gtk_timeout_add' from incompatible pointer type如果你当时不是这样定义read_fifo的,就会出现
发表于 2004-8-3 08:42:47 | 显示全部楼层

  1. 但如果使用flush函数,则其中的printf语句不能打印正确结果,而前面那个printf打印出空结果。
复制代码

前面那个printf指哪一个?
发表于 2004-8-3 08:50:25 | 显示全部楼层

  1.     char buff[64] = "\0";
  2.     read(ffd, buff, 64);
复制代码

这样处理是有问题的,你的buff最终不一定以'\0'结尾

  1. #define BUFSIZE 65
  2. char buff[BUFSIZE];
  3. memset(buff, 0, sizeof(buff));
  4. read(ffd, buff, sizeof(buff) - 1);
复制代码
 楼主| 发表于 2004-8-3 11:59:54 | 显示全部楼层
谢谢。我所说的前一个printf是指read_fifo()中flush()下面的那个,打印读到的数据。
我昨天调试的结果就是发现受for循环的影像,得不到数据,原因还不清楚,正如我在上面说的--仅仅改变flush()中的一个循环的条件,read_fifo()中的那个printf应该不受影像才对呀,它只打印读取到的原始数据。
另外,我使用了一个GtkCurve,想要用图表的形式打印出流量数据,用gtk_curve_set_verctor(GTK_CURVE(widget), v[ ])进行设置,但好像没有效果。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表