【问题标题】:GTK+3 compile error "Could not find signal handler `` Did you compile with -rdynamic?GTK+3 编译错误“找不到信号处理程序 `` 你用 -rdynamic 编译了吗?
【发布时间】:2021-05-30 10:46:32
【问题描述】:

我正在使用 Glade 和 GTK+3 制作 GUI。我学习了许多教程,阅读了许多论坛帖子,但我仍然可以摆脱“Gtk-WARNING **:14:50:06.794:找不到信号处理程序'on_window_main_destroy'。你用-rdynamic编译了吗?”我收到的每个信号的警告。请帮忙。这个问题真是要死我了!

我在 Glade 中制作了一个简单的 GUI。它由主窗口、固定网格、两个刻度和连接到刻度的两个调整组成。我已将信号连接到主窗口“destroy”“on_window_main_destroy”和调整“value changed -> on_adjustment_scale_exposure_value_changed”和“value changed -> on_adjustment_scale_gain_value_changed”。

然后我使用 geany 编写了代码。无论我尝试什么,每次运行程序时,我都会收到所有信号的上述错误消息。

在 Glade 中,我尝试过使用普通的 save as 和 save as "builder" 文件。没有区别。

我尝试过许多不同的 g++ 和 gcc 命令,但没有任何区别。

空地代码:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
  <requires lib="gtk+" version="3.20"/>
  <object class="GtkAdjustment" id="adjustment_scale_exposure">
    <property name="lower">1</property>
    <property name="upper">1000</property>
    <property name="value">10</property>
    <property name="step_increment">1</property>
    <property name="page_increment">10</property>
    <signal name="value-changed" handler="on_adjustment_scale_exposure_value_changed" swapped="no"/>
  </object>
  <object class="GtkAdjustment" id="adjustment_scale_gain">
    <property name="lower">1</property>
    <property name="upper">20</property>
    <property name="value">1</property>
    <property name="step_increment">1</property>
    <property name="page_increment">10</property>
    <signal name="value-changed" handler="on_adjustment_scale_gain_value_changed" swapped="no"/>
  </object>
  <object class="GtkWindow" id="window_main">
    <property name="width_request">1024</property>
    <property name="height_request">600</property>
    <property name="can_focus">False</property>
    <property name="border_width">5</property>
    <signal name="destroy" handler="on_window_main_destroy" swapped="no"/>
    <child>
      <placeholder/>
    </child>
    <child>
      <object class="GtkFixed">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <child>
          <object class="GtkScale" id="scale_exposure">
            <property name="width_request">30</property>
            <property name="height_request">600</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="orientation">vertical</property>
            <property name="adjustment">adjustment_scale_exposure</property>
            <property name="inverted">True</property>
            <property name="round_digits">1</property>
            <property name="digits">0</property>
            <property name="value_pos">bottom</property>
          </object>
        </child>
        <child>
          <object class="GtkScale" id="scale_gain">
            <property name="width_request">30</property>
            <property name="height_request">600</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="orientation">vertical</property>
            <property name="adjustment">adjustment_scale_gain</property>
            <property name="inverted">True</property>
            <property name="round_digits">1</property>
            <property name="value_pos">bottom</property>
          </object>
          <packing>
            <property name="x">30</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

编写代码:

#include "gtk/gtk.h"

GtkWidget *g_scale_exposure;
GtkAdjustment *g_adjustment_scale_exposure;
GtkWidget *g_scale_gain;
GtkAdjustment *g_adjustment_scale_gain;
GtkWidget *g_lbl_exposure;
GtkWidget *g_lbl_gain;

int main (int argc, char* argv[]){

    GtkBuilder *builder;
    GtkWidget *window;

    gtk_init(&argc, &argv);

    builder = gtk_builder_new();
    gtk_builder_add_from_file(builder, "main.glade", NULL);

    window = GTK_WIDGET(gtk_builder_get_object(builder, "window_main"));
    gtk_builder_connect_signals(builder, NULL);

    g_scale_exposure = GTK_WIDGET(gtk_builder_get_object(builder, "scale_exposure"));
    g_scale_gain = GTK_WIDGET(gtk_builder_get_object(builder, "scale_gain"));
    g_adjustment_scale_exposure = GTK_ADJUSTMENT(gtk_builder_get_object(builder, "adjustment_scale_exposure"));
    g_adjustment_scale_gain = GTK_ADJUSTMENT(gtk_builder_get_object(builder, "adjustment_scale_gain"));
    g_lbl_exposure = GTK_WIDGET(gtk_builder_get_object(builder, "lbl_exposure"));
    g_lbl_gain = GTK_WIDGET(gtk_builder_get_object(builder, "lbl_gain"));

    g_object_unref(builder);

    gtk_widget_show(window);
    gtk_main();

    return 0;
}

void on_window_main_destroy(){
    gtk_main_quit();
}

void on_adjustment_scale_exposure_value_changed(GtkAdjustment *adjustment_scale_exposure, gpointer data){
    int scaleValue = gtk_adjustment_get_value(GTK_ADJUSTMENT(g_adjustment_scale_exposure));

    printf("moi, %d\n", scaleValue);

}

void on_adjustment_scale_gain_value_changed(GtkAdjustment *adjustment_scale_gain, gpointer data){
    float scaleValue = gtk_adjustment_get_value(GTK_ADJUSTMENT(g_adjustment_scale_gain));
    printf("moi2, %f\n", scaleValue);

}

g++ 代码:

g++ -rdynamic -Wall  normiApiTestiGlade2.cpp -o runme `pkg-config --cflags --libs gtk+-3.0 gmodule-2.0`

预期结果是在连接信号的情况下运行 GUI。现在 GUI 启动了,我可以移动滑块,但没有任何改变(除了在 gui 中)。

警告: (runme:18098): Gtk-WARNING **: 15:09:26.660: 找不到信号处理程序'on_window_main_destroy'。你是用 -rdynamic 编译的吗?

(runme:18098): Gtk-WARNING **: 15:09:26.660: 找不到信号处理程序“on_adjustment_scale_gain_value_changed”。你是用 -rdynamic 编译的吗?

(runme:18098): Gtk-WARNING **: 15:09:26.660: 找不到信号处理程序“on_adjustment_scale_exposure_value_changed”。你是用 -rdynamic 编译的吗?

【问题讨论】:

  • 我使用的是 Ubuntu 18.04、Glade 3.22.1、GTK+3
  • 错误信息清楚地询问“你用-rdynamic编译了吗?”您发布的编译器命令行清楚地表明您。那么,您是否尝试过那样做?
  • 是的,我尝试过不使用 -rdynamic。结果相同

标签: c++ gtk3


【解决方案1】:

gtk_builder_connect_signals 拥有您需要的所有信息。

在没有明确添加符号的情况下; 它使用 GModule 的内省功能...查看应用程序的符号表...

如果依赖 GModule 支持在符号表中查找回调,应注意以下细节:

在为 Windows 编译应用程序时,必须使用 G_MODULE_EXPORT 声明信号回调,否则它们将不会放入符号表中。在 Linux 和 Unices 上,这不是必需的;应改为使用 -Wl,--export-dynamic CFLAGS 编译应用程序,并与 gmodule-export-2.0 链接。

您必须将 -Wl,--export-dynamic (原文如此) 传递给编译器。

【讨论】:

  • 感谢您的澄清,虽然我不太明白。应该在 g++ 行的哪个位置插入 --export-dynamic 和 -Wl ?顺便说一句,我通过为每个信号调用 g_signal_connect 来使程序正常工作。我仍然收到原始错误,但信号有效。
  • @Dan gcc so.c -Wl,--export-dynamic `pkg-config --cflags --libs gtk+-3.0` &amp;&amp; ./a.out 我就是这样编译的。
  • 与您的 gcc 行的结果相同。我开始认为这是一个 Glade 问题。但不知道为什么......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-06
  • 2011-04-23
  • 1970-01-01
  • 1970-01-01
  • 2013-10-08
  • 2023-03-03
相关资源
最近更新 更多