3

我正在构建一个 GTK+ gui,我正在尝试使用 GtkBuilder 来完成它。

有一个主窗口,其中有一个笔记本、一个菜单和两个按钮。当我点击一个按钮时,我想用标签填充笔记本。

所以我从一个带有 GtkBuilder 的文件创建了主窗口,然后我尝试将每个选项卡添加到构建器中。

现在,我这样做了(未缩进的代码是调试打印)

#include <stdio.h>
#include <stdlib.h>

#include <string.h>

#include <gtk/gtk.h>

#include "main.h"

GtkBuilder* build;
int i;

#define TAB\
  "<interface>\
    <object class=\"GtkNotebook\" id=\"note\">\
      <property name=\"scrollable\">t</property>\
      <property name=\"show-border\">t</property>\
      <property name=\"show-tabs\">t</property>\
      <child>\
        <object class=\"GtkLabel\" id=\"tab%d\">\
          <property name=\"label\">Content%d</property>\
        </object>\
      </child>\
      <child type=\"tab\">\
        <object class=\"GtkLabel\" id=\"labTab%d\">\
          <property name=\"label\">Label%d</property>\
        </object>\
      </child>\
    </object>\
  </interface>"

int main(int argc, char** argv) {
  GtkWidget* window;
//  GtkWidget* item;
  GError* error=NULL;
  GtkAccelGroup* accel_group;

  i=0;

  gtk_init(&argc, &argv);

  build=gtk_builder_new();
  if (gtk_builder_add_from_file(build, "gui.ui", &error)==0)
    printf("erreur %s\n", error->message);

  gtk_builder_add_callback_symbol(build, "quit", func);
  gtk_builder_add_callback_symbol(build, "add", add);

  gtk_builder_connect_signals(build, NULL);

  window=(GtkWidget*)gtk_builder_get_object(build, "main");
  gtk_window_maximize(GTK_WINDOW(window));

  gtk_widget_show_all(window);

  gtk_main();


  return EXIT_SUCCESS;
}

void add() {
  char* str;
  GtkWidget* window;
  GError* error=NULL;
  FILE* file=NULL;

printf("in add 1\n");
  if ((str=malloc(sizeof(TAB)+20))==NULL) {
    perror("malloc");
    exit(EXIT_FAILURE);
  }
printf("in add 2\n");

  snprintf(str, sizeof(TAB)+20, TAB, i, i, i, i);
printf("in add 3, str : %s\n", str);

  if ((file=fopen("tmp.ui", "w"))==NULL) {
    free(str);
    perror("fopen");
    exit(EXIT_FAILURE);
  }

  fprintf(file, TAB, i, i, i, i);

  fclose(file);

/*  if (gtk_builder_add_from_file(build, "tmp.ui", &error)==0)
    printf("erreur %s\n", error->message);*/
  if (gtk_builder_add_from_string(build, str, sizeof(str), &error)==0)
    printf("erreur %s\n", error->message);
printf("in add 4\n");

  if ((window=(GtkWidget*)gtk_builder_get_object(build, "main"))==NULL)
    printf("Can't find\n");
  else
    gtk_widget_show_all(window);

  sprintf(str, "tab%d", i);
  if ((window=(GtkWidget*)gtk_builder_get_object(build, str))==NULL)
    printf("in add, Does not exist (%s)\n", str);
  else
    printf("in add, Exist (%s)\n", str);

  remove("tmp.ui");
  free(str);
  ++i;
//  free(error);
}

这是我的构建器定义:

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <!-- Main window -->
  <object class="GtkWindow" id="main">
    <property name="title">Test Xml</property>
    <property name="window-position">GTK_WIN_POS_CENTER</property>
    <property name="default-width">1024</property>
    <property name="default-height">512</property>
    <signal name="delete-event" handler="quit"/>

    <child>
      <object class="GtkBox" id="mainBox">
        <property name="orientation">GTK_ORIENTATION_VERTICAL</property>
        <property name="spacing">5</property>

        <!-- Menu -->
        <child>
          <object class="GtkMenuBar" id="menuBar">
            <child>

              <!-- Menu fichier -->
              <object class="GtkMenuItem" id="m1">
                <property name="label">_Fichier</property>
                <property name="use_underline">True</property>
                <child type="submenu">
                  <object class="GtkMenu" id="menu">
                    <property name="accel-group">accel_group</property>
                    <child>

                      <!-- Item Quitter -->
                      <object class="GtkMenuItem" id="i1">
                        <property name="accel-path">&lt;Test&gt;/FILE/QUIT</property>
                        <property name="label">_Quitter</property>
                        <property name="use_underline">True</property>
                        <signal name="activate" handler="quit"/>
                      </object>
                      <!-- End Item Quitter -->

                    </child>
                  </object>
                </child>
              </object>
              <!-- End Menu fichier -->

            </child>
          </object>
        </child>
        <!-- End Menu -->

        <!-- Frame -->
        <child>
          <object class="GtkFrame" id="mainframe">
            <property name="expand">t</property>

            <!-- Note book -->
            <child>
              <object class="GtkNotebook" id="note">
                <property name="scrollable">t</property>
                <property name="show-border">t</property>
                <property name="show-tabs">t</property>
              </object>
            </child>
            <!-- Note book -->
          </object>
        </child>
        <!-- End Frame -->

        <!-- Bottom box -->
        <child>
          <object class="GtkBox" id="bottomBox">
            <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
            <property name="spacing">5</property>

            <!-- Buttons -->
            <child>
              <object class="GtkButton" id="boutonPlus">
                <property name="label">_Ajouter</property>
                <property name="use-underline">t</property>
                <signal name="activate" handler="add"/>
              </object>
            </child>
            <child>
              <object class="GtkButton" id="boutonMoins">
                <property name="label">_Enlever</property>
                <property name="use-underline">t</property>
              </object>
            </child>
            <!-- End buttons -->
          </object>
        </child>
        <!-- End Bottom box -->
      </object>
    </child>
  </object>
</interface>

这是输出:

in add 1
in add 2
in add 3, str : <interface>
    <object class="GtkNotebook" id="note">
      <property name="scrollable">t</property>
      <property name="show-border">t</property>
      <property name="show-tabs">t</property>
      <child>
        <object class="GtkLabel" id="tab0">
          <property name="label">Content0</property>
        </object>
      </child>
      <child type="tab">
        <object class="GtkLabel" id="labTab0">
          <property name="label">Label0</property>
        </object>
      </child>
    </object>
  </interface>
in add 4
in add, Does not exist (tab0)

正如我们所看到的,该选项卡没有添加到构建器中,但是当我添加它时似乎没有错误。

  • 在文档中说,如果我们想合并一些 ui 定义,我们必须使用gtk_builder_new(),然后使用gtk_builder_add_from_...(). 所以我做到了,在我的add函数中,我尝试从字符串或文件添加选项卡只是为了查看问题是因为我开始从文件添加然后从字符串添加,但它没有。
  • 在文档中,我没有找到任何关于合并所需的内容。因此,要添加选项卡,我尝试了使用/不使用<interface>和 nodebook 定义。但这并没有改变什么。

是否有一些关于将 ui 定义与 a 合并的文档GtkBulder,或者有人可以解释我做错了什么?

4

0 回答 0