c - 交换 GList (GLib) 中的两个项目

标签 c glib

我很难弄清楚如何交换 glist 中的两个项目。我需要交换列表中的两个项目,以便在渲染时它们的顺序发生变化。我怎样才能做到这一点?

如何才能在列表中上移和下移项目。

例如,我想制作在 gtktreeview 中向上或向下移动项目的函数。我尝试这样做来提升:

    typedef struct Settings settings;
    struct Settings
    {
        GList *l;
    };

    typedef struct Preset preset;
    struct Preset
    {
        char* title;
        float freq;
    };

    settings sts;

    void move_up_button(GtkWidget *widget, gpointer(data))
    {
        preset *ps;
        int *row, pos;
        .....................................

        row = gtk_tree_path_get_indices(path);

        ps = g_list_nth_data(sts.l, *row);
        g_assert(ps);

        pos = g_list_index(sts.l, (gpointer)ps);
        pos--;

        sts.l = g_list_remove(sts.l, (gpointer)ps);
        sts.l = g_list_insert(sts.l, (gpointer)ps, pos);

        .......................................
    }

如何在不使用删除和插入 Glist 函数的情况下简化此操作?

谢谢

最佳答案

我假设您正在谈论列表中的连续元素。

在这种情况下,让 A 和 B 代表您想要交换的两个元素(按顺序)。那么您需要确保

  • 指向 A 的元素(即位于它之前的元素)改为指向 B;
  • A 指向当前 B 所指向的元素;和
  • B 指向 A。

试试这个:

GList *element_a, *element_b;

...

/* Swap elements A and B */
element_a->prev->next = element_b;
element_b->prev = element_a->prev;

element_a->next = element_b->next;
element_b->next->prev = element_a;

element_b->next = element_a;
element_a->prev = element_b;
<小时/>

编辑:鉴于您添加到问题中的代码,请尝试使用此操作,该操作会操作列表元素的指针,而不是使用 g_list_removeg_list_insert:

GList *button_element, *preceding_element;

....

row = gtk_tree_path_get_indices(path);

button_element = g_list_nth(sts.l, *row);
g_assert(button_element->data);

/* Swap the button with its preceding element, if there is one */
preceding_element = button_element->prev;
if(preceding_element) {
  if(preceding_element->prev) {
    preceding_element->prev->next = button_element;
    button_element->prev = preceding_element->prev;
  }
  else {
    /* The preceding element is the head of the list, which we must update */
    sts.l = button_element;
    button_element->prev = NULL;
  }

  preceding_element->next = button_element->next;
  if(button_element->next) {
    button_element->next->prev = preceding_element;
  }

  button_element->next = preceding_element;
  preceding_element->prev = button_element;
}

关于c - 交换 GList (GLib) 中的两个项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25077628/

相关文章:

c++ - 头文件在整个程序中只包含一次?

c - eclipse CDT : Glib headers not parsed correctly

c - 找不到 glib.h

c - 如何通过 Soupsession 或 SoapMessage 信号检测错误?

c - 如何分配内存并将其返回(通过指针参数)给调用函数?

c - malloc.c 中如何/在哪里使用 sbrk?

c - 带参数函数的 printf 返回指向 char 的指针

c - 从输入文件中打印 5 行

c - 使用 glibc 进行单元测试会导致 g_test_fail() 出现段错误

c - 通过glib队列传递数据结构