GTK IOChannel - 如何处理 G_IO_IN 事件
GTK IOChannel - How to deal with G_IO_IN event
感谢您花时间回答我的问题!
我的目标:读取日志文件,将其显示到 TextView 小部件中,然后在每次向文件添加新行时更新它(看起来很简单)
问题:似乎总是满足 G_IO_IN 条件,即使 G_STATUS_EOF 也是如此。因此,程序挂起并且不显示任何内容。
以下是一些代码摘录:
1、打开文件,读取并显示到 TextView 中(完美运行):
// Get the TextBuffer then go to the latest position (not sure it is useful)
txtBuf=gtk_text_view_get_buffer((GtkTextView *)tvLogs);
gtk_text_buffer_get_end_iter(txtBuf, &txtIter);
// Connect logfile to new IOChannel and add_watch to G_IO_IN condition
chanErr=g_io_channel_new_file("./errorlog.log","r", &error);
g_io_add_watch(chanErr, G_IO_IN, (GIOFunc)DisplayLogs, NULL);
// Read the whole file and display it into the TextView
ret=g_io_channel_read_to_end(chanErr,&file, &fileLen, &err)
g_assert(ret == G_IO_STATUS_NORMAL);
// Insert file read into the TextView
gtk_text_buffer_insert(txtBuf, &txtIter, file, fileLen);
至此,一切都运行好了...这是连接到G_IO_IN条件的回调:
gboolean DisplayLogs(GIOChannel *chanErr, GIOCondition cond, gpointer data)
{
GtkWidget *tvLogs;
gchar *buf;
gsize bufLen;
GError *err=NULL;
GtkTextBuffer *txtBuf;
GtkTextIter txtIter;
GIOStatus ret;
// Retrieve the TextView
tvLogs=GTK_WIDGET(gtk_builder_get_object(builder,(gchar*)"tvLogs"));
g_assert(tvLogs);
// Try to read 1 line
ret=g_io_channel_read_line(chanErr, &buf, &bufLen, NULL, &err);
if (ret!=G_STATUS_NORMAL) {
switch (ret) {
case G_IO_STATUS_ERROR : g_warning("G_IO_STATUS_ERROR"); break;
case G_IO_STATUS_EOF : g_warning("G_IO_STATUS_EOF"); break;
case G_IO_STATUS_AGAIN : g_warning("G_IO_STATUS_AGAIN"); break;
}
if (err)
g_warning(err->message);
}
//
....
other stuff to update info displayed but never reached
//
return TRUE;
}
当应用程序启动时:它在 "G_STATUS_EOF" 上无限循环。
似乎此事件触发 G_IO_IN 条件并触发回调。
有什么想法吗?
非常感谢。
此致。
--
文森特
嗯,既然没人回答,我只好自己想办法了(这确实是一件好事)。
问题是:如何在 TextView 中显示来自文件的日志条目。
找到的解决方案:
- 为了生成日志,应用程序使用 zlog API 因此,我没有查看日志文件、读取新条目并将它们显示在文本视图中,而是执行了以下操作:
- 在 zlog 中添加自定义输出回调 API(API 的非常好的功能)
- 回调只是 "print" 将 zlog 格式的消息(日期 - 时间 - 函数 - 严重性 - 消息)放入 TextView 小部件的末尾。
- 同时,ZLog 将消息写入日志文件(由于 zlog.conf 文件)。
结果很好。我有日志文件和窗口日志。
问题已解决(或解决方法取决于 :-))
此致。
感谢您花时间回答我的问题!
我的目标:读取日志文件,将其显示到 TextView 小部件中,然后在每次向文件添加新行时更新它(看起来很简单)
问题:似乎总是满足 G_IO_IN 条件,即使 G_STATUS_EOF 也是如此。因此,程序挂起并且不显示任何内容。
以下是一些代码摘录:
1、打开文件,读取并显示到 TextView 中(完美运行):
// Get the TextBuffer then go to the latest position (not sure it is useful)
txtBuf=gtk_text_view_get_buffer((GtkTextView *)tvLogs);
gtk_text_buffer_get_end_iter(txtBuf, &txtIter);
// Connect logfile to new IOChannel and add_watch to G_IO_IN condition
chanErr=g_io_channel_new_file("./errorlog.log","r", &error);
g_io_add_watch(chanErr, G_IO_IN, (GIOFunc)DisplayLogs, NULL);
// Read the whole file and display it into the TextView
ret=g_io_channel_read_to_end(chanErr,&file, &fileLen, &err)
g_assert(ret == G_IO_STATUS_NORMAL);
// Insert file read into the TextView
gtk_text_buffer_insert(txtBuf, &txtIter, file, fileLen);
至此,一切都运行好了...这是连接到G_IO_IN条件的回调:
gboolean DisplayLogs(GIOChannel *chanErr, GIOCondition cond, gpointer data)
{
GtkWidget *tvLogs;
gchar *buf;
gsize bufLen;
GError *err=NULL;
GtkTextBuffer *txtBuf;
GtkTextIter txtIter;
GIOStatus ret;
// Retrieve the TextView
tvLogs=GTK_WIDGET(gtk_builder_get_object(builder,(gchar*)"tvLogs"));
g_assert(tvLogs);
// Try to read 1 line
ret=g_io_channel_read_line(chanErr, &buf, &bufLen, NULL, &err);
if (ret!=G_STATUS_NORMAL) {
switch (ret) {
case G_IO_STATUS_ERROR : g_warning("G_IO_STATUS_ERROR"); break;
case G_IO_STATUS_EOF : g_warning("G_IO_STATUS_EOF"); break;
case G_IO_STATUS_AGAIN : g_warning("G_IO_STATUS_AGAIN"); break;
}
if (err)
g_warning(err->message);
}
//
....
other stuff to update info displayed but never reached
//
return TRUE;
}
当应用程序启动时:它在 "G_STATUS_EOF" 上无限循环。 似乎此事件触发 G_IO_IN 条件并触发回调。
有什么想法吗?
非常感谢。
此致。
-- 文森特
嗯,既然没人回答,我只好自己想办法了(这确实是一件好事)。
问题是:如何在 TextView 中显示来自文件的日志条目。
找到的解决方案:
- 为了生成日志,应用程序使用 zlog API 因此,我没有查看日志文件、读取新条目并将它们显示在文本视图中,而是执行了以下操作:
- 在 zlog 中添加自定义输出回调 API(API 的非常好的功能)
- 回调只是 "print" 将 zlog 格式的消息(日期 - 时间 - 函数 - 严重性 - 消息)放入 TextView 小部件的末尾。
- 同时,ZLog 将消息写入日志文件(由于 zlog.conf 文件)。
结果很好。我有日志文件和窗口日志。
问题已解决(或解决方法取决于 :-))
此致。