Gtk::Label 更新标签速度

Posted

技术标签:

【中文标题】Gtk::Label 更新标签速度【英文标题】:Gtk::Label update label speed 【发布时间】:2014-03-23 15:07:04 【问题描述】:

我有一个程序试图以非常高的频率更新 Gtk::Label,并且表现出非常不稳定的行为。我收到了其中几个错误:

(gtkWindow:26559): Pango-CRITICAL **: pango_layout_copy: assertion 'PANGO_IS_LAYOUT (src)' failed

(gtkWindow:26559): Pango-CRITICAL **: pango_layout_set_width: assertion 'layout != NULL' failed

(gtkWindow:26559): Pango-CRITICAL **: pango_layout_get_pixel_extents: assertion 'PANGO_IS_LAYOUT (layout)' failed

(gtkWindow:26559): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed

直到程序最终崩溃:

Pango:ERROR:pango-layout.c:3916:pango_layout_check_lines: assertion failed: (!layout->log_attrs)

2921 中止(核心转储)

相关代码行:

while(1)
    std::string sensorLine="";
    _serial.readLine(&sensorLine);         // read serial data with boost::asio
    _output->set_label(sensorLine.data()); // _output -> Gtk::Label*
    std::cout<<sensorLine<<std::endl;
    //sleep(1);

如果我尝试使用_output-&gt;setlabel,我只会收到错误消息,如果我评论这一行,一切都会顺利运行,输出会打印在控制台中。如果我在循环内调用sleep(),也会发生同样的事情,Gtk::Label 会作为命令行更新,并且不会引发任何错误。 此循环在接收 _output 作为参数的单独线程上运行。

【问题讨论】:

说真的,对您提供给set_label 的数据进行完整性检查。它需要以空值结尾... std::string 不是已经有这种检查了吗? 【参考方案1】:

g_idle_add(实际上线程安全的)与回调一起实际修改(阅读:调用set_label)你的GtkLabel


不要从不同的线程调用 UI 函数!永远不会!如果你打开了潘多拉的盒子。

【讨论】:

所以我应该放弃我的单独线程吗?还是先把数据传给g_idle_add再调用set_label 这取决于传感器的 IO 是否长时间阻塞。如果是长时间操作(ms 的 10 秒),请使用单独的线程(循环并使用 g_idle_add),否则您可以使用 g_timeout_add 并在回调中读取传感器。 现在我正在使用 g_idle_add 回调来读取由我的单独线程更新的共享 std::string*,我遇到了几个分段错误和 Glib 错误。 嗯,您正在从 2 个不同的线程访问可能发生变化的数据。那会坏掉的。复制数据,只是 g_memdupg_free。还显示更多代码确实会有所帮助(最小的可编译示例)。 我有一个类似的问题,我从另一个线程中更新状态栏 - 不执行此状态更新删除了严重的错误消息 - 但是,我怎样才能安全地从线程中更新我的状态栏???

以上是关于Gtk::Label 更新标签速度的主要内容,如果未能解决你的问题,请参考以下文章

GTK3 在按钮标签中换行

gtk编程中标签控件设置了gtk_label_set_line_wrap(GTK_LABEL(label),TRUE);为啥也不能自动换行呢?

在 tabBar didSelectItem 上加载核心数据的替代方法?还是加快速度?

Yandex metrika 标签减慢网站速度谷歌页面速度 isights 报告

从另一个小部件触发检查按钮悬停事件

赶快使用 Firefox 57吧! 速度比以前快2倍