Gtk::Label 更新标签速度

joa*_*dre 0 c++ gtk multithreading gtkmm

我有一个程序试图以非常高的频率更新 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
Run Code Online (Sandbox Code Playgroud)

直到程序最终崩溃:

Pango:ERROR:pango-layout.c:3916:pango_layout_check_lines: assertion failed: (!layout->log_attrs)
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

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

dra*_*hnr 5

使用g_idle_add(实际上线程安全的)与回调实际上修改(读取:调用set_label)您的GtkLabel.


不要从不同的线程调用 UI 函数!永远不能!如果你这样做,你就会打开潘多拉的盒子。