我在使用旋转按钮调整时遇到了一个问题。我想要做的是响应单选按钮切换信号,我想更改与旋转按钮相关的调整。因此,旋转按钮切换信号的处理程序获取传递给它的旋转按钮。调整本身是全局的,因此无需通过它们。附上示例代码。如果我不重新初始化处理程序中的调整(注释代码),当处理程序运行并尝试调整微调按钮值时,我会收到所有警告/错误。顺便说一句,我在 Rpi3B+ 上运行此代码。单击单选按钮“Pgm by DAC Code”可以工作 - 它会根据要求更改旋转按钮值。但是,当单击“Pgm by Voltage”单选按钮时,pgm 行为异常,如下面的控制台窗口输出所示。
(adjustment_issue:4441): GLib-GObject-CRITICAL **: g_object_ref_sink: assertion 'G_IS_OBJECT (object)' failed
(adjustment_issue:4441): GLib-GObject-WARNING **: instance with invalid (NULL) class pointer
(adjustment_issue:4441): GLib-GObject-CRITICAL **: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed
(adjustment_issue:4441): GLib-GObject-WARNING **: instance with invalid (NULL) class pointer
(adjustment_issue:4441): GLib-GObject-CRITICAL **: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed
(adjustment_issue:4441): Gtk-CRITICAL **: gtk_adjustment_get_step_increment: assertion 'GTK_IS_ADJUSTMENT (adjustment)' failed
(adjustment_issue:4441): Gtk-CRITICAL **: gtk_spin_button_value_changed: assertion 'GTK_IS_ADJUSTMENT (adjustment)' failed
/*
* adjustment_issue.c.c
*
*/
#include <math.h>
#include <gtk/gtk.h>
typedef struct {
GtkWidget *sblblVdc;
GtkWidget *sbVdc;
} dcvWidgets_t;
// structure to hold the data for adjustments
typedef struct {
double initVal;
double minVal;
double maxVal;
double stepVal;
} adj_t;
adj_t vdcLimits;
adj_t dacCodeLimits;
GtkAdjustment *adjSbVoltLimits;
GtkAdjustment *adjSbCodeLimits;
static void dcPgmModeChanged(GtkToggleButton *btn, dcvWidgets_t *dcvWid)
{
// BUG WORKAROUND: Re-initialize the adjustments.
// When the Pgm by Code rb is clicked, all is well.
// But when the Pgm by Voltage is clicked, the sbVoltLimits adjustment
// appears to point to nothing and program displays lots of errors in
// terminal window.
if (gtk_toggle_button_get_active(btn)) {
/*
adjSbVoltLimits = gtk_adjustment_new(
vdcLimits.initVal, vdcLimits.minVal, vdcLimits.maxVal,
vdcLimits.stepVal, 0, 0);
*/
// modify the spin button to show voltage range
gtk_spin_button_configure(GTK_SPIN_BUTTON(dcvWid->sbVdc),
adjSbVoltLimits, 0, 3);
}
else {
/*
adjSbCodeLimits = gtk_adjustment_new(
dacCodeLimits.initVal, dacCodeLimits.minVal, dacCodeLimits.maxVal,
dacCodeLimits.stepVal, 0, 0);
*/
// modify the spin button to show DAC code range
gtk_spin_button_configure(GTK_SPIN_BUTTON(dcvWid->sbVdc),
adjSbCodeLimits, 0, 0);
}
}
static void activate(GtkApplication* app, gpointer user_data)
{
GtkWidget *window;
dcvWidgets_t *dcvWidgets = g_slice_new(dcvWidgets_t);
window = gtk_application_window_new(app);
gtk_window_set_title(GTK_WINDOW(window), "GTK Adjustment Issue");
gtk_window_set_default_size(GTK_WINDOW(window), 400, -1);
GtkWidget *hbx = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
vdcLimits.initVal = 2.5;
vdcLimits.minVal = 0.0;
vdcLimits.maxVal = 4.999;
vdcLimits.stepVal = 0.001;
adjSbVoltLimits = gtk_adjustment_new(
vdcLimits.initVal, vdcLimits.minVal, vdcLimits.maxVal,
vdcLimits.stepVal, 0, 0);
dacCodeLimits.initVal = 2048;
dacCodeLimits.minVal = 0;
dacCodeLimits.maxVal = 4095;
dacCodeLimits.stepVal = 1;
adjSbCodeLimits = gtk_adjustment_new(
dacCodeLimits.initVal, dacCodeLimits.minVal, dacCodeLimits.maxVal,
dacCodeLimits.stepVal, 0, 0);
dcvWidgets->sbVdc = gtk_spin_button_new(adjSbVoltLimits, 0, 3);
gtk_entry_set_width_chars(GTK_ENTRY(dcvWidgets->sbVdc), 5);
GtkWidget *rb1Mode = gtk_radio_button_new_with_label(NULL, "Pgm. by voltage");
GtkWidget *rb2Mode = gtk_radio_button_new_with_label_from_widget(
GTK_RADIO_BUTTON(rb1Mode), "Pgm. by DAC code");
g_signal_connect(rb1Mode, "toggled",
G_CALLBACK(dcPgmModeChanged), dcvWidgets);
GtkWidget *vboxMode = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_box_pack_start(GTK_BOX(vboxMode), rb1Mode, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(vboxMode), rb2Mode, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(hbx), vboxMode, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(hbx), dcvWidgets->sbVdc, FALSE, FALSE, 0);
gtk_container_add(GTK_CONTAINER(window),hbx);
gtk_widget_show_all(window);
}
int main(int argc, char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new("org.gtk.example", G_APPLICATION_FLAGS_NONE);
g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}