首页 > 解决方案 > C、GTK3 在滚动窗口中传播自然高度不能正常工作

问题描述

我正在尝试用 GTK3 用 C 语言编写我的第一个程序。我的目标是创建一个应用程序窗口,里面有一个盒子(mainbox)。在此框内有一个带有树视图的滚动窗口和该滚动窗口下方的一些按钮。如果我单击一个按钮,该框将被销毁并创建一个新框,用于创建或修改某些数据以稍后在 Treeview 中显示。从这个新窗口可以返回到主窗口。当用户想要返回时,实际的盒子将被销毁并再次创建第一个盒子(主盒子)。当程序第一次启动并创建主框时,滚动窗口将正确调整大小,因为 gtk_scrolled_window_get_propagate_natural_height 设置为 TRUE。当我销毁容器时,创建一个新容器,然后在主框中再次返回(销毁实际并再次创建第一个容器),滚动窗口的大小错误并且只显示一行(滚动条处于活动状态)。这是我的代码:

主程序

#include <gtk/gtk.h>
#include "general.h"


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

    GtkApplication *app;
    int status;

    app = gtk_application_new ("emergencyroom", G_APPLICATION_FLAGS_NONE);
    g_signal_connect (app, "activate", G_CALLBACK (create_mainwin), NULL);
    status = g_application_run (G_APPLICATION (app), argc, argv);
    g_object_unref (app);

    return status;
}

主窗口功能

void create_mainwin(GtkApplication* app, gpointer user_data){
    //stMainwin *widgets = g_slice_new(stMainwin);
    GtkWidget *main_win;


    main_win = gtk_application_window_new(app);
    gtk_window_set_decorated(GTK_WINDOW(main_win),TRUE);
    gtk_window_set_position(GTK_WINDOW(main_win), GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(main_win),1024,768);
    gtk_window_maximize(GTK_WINDOW(main_win));
    gtk_window_set_title(GTK_WINDOW(main_win),"Emergency Room 1.0");

    g_signal_connect(G_OBJECT (main_win), "delete-event",
                     G_CALLBACK(close_main), main_win);
    g_signal_connect(G_OBJECT(main_win), "draw",G_CALLBACK(gtk_widget_queue_draw),NULL);


    gtk_widget_show_all(main_win);
    main_box(main_win);

}

主箱功能

void main_box(GtkWidget *main_win){

    enum{
        SVNR,
        Vorname,
        Nachname,
        Datum,
        //NOME,
        N_COLUMNS
    };


    GtkWidget *trMain;
    GtkTreeViewColumn *column;
    GtkTreeIter iter;

    GtkBuilder *builder ;

    builder = gtk_builder_new();
    gtk_builder_add_from_file (builder, "/home/carlo/Nextcloud/FH/HWSE2/HWSE-Projekt/hwse/main_box.glade", NULL);
    stMainwin *widgets = g_slice_new(stMainwin);

    widgets->main_win = main_win;
    widgets->scroll = GTK_WIDGET(gtk_builder_get_object(builder,"scroll"));

    GtkCellRenderer *renderer, *renderer1;

    widgets->listdel = gtk_list_store_new(4,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING);

    widgets->box = GTK_WIDGET(gtk_builder_get_object(builder,"box"));

    trMain = GTK_WIDGET(gtk_builder_get_object(builder,"trMain"));

    gtk_tree_view_set_model(GTK_TREE_VIEW(trMain),GTK_TREE_MODEL(widgets->listdel));

    renderer = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes("SVNR",renderer,"text",SVNR,NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(trMain), GTK_TREE_VIEW_COLUMN(column));
    column = gtk_tree_view_column_new_with_attributes("Vorname",renderer,"text",Vorname,NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(trMain), GTK_TREE_VIEW_COLUMN(column));
    column = gtk_tree_view_column_new_with_attributes("Nachname", renderer, "text", Nachname,NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(trMain), GTK_TREE_VIEW_COLUMN(column));
    column = gtk_tree_view_column_new_with_attributes("Empfangsdatum",renderer, "text", Datum,NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(trMain), GTK_TREE_VIEW_COLUMN(column));

    gtk_list_store_append (GTK_LIST_STORE(widgets->listdel), &iter);
    gtk_list_store_set (GTK_LIST_STORE(widgets->listdel),&iter,0,"1",1,"Name1",2,"Fmname2",3,"heute",-1);
    gtk_list_store_append (GTK_LIST_STORE(widgets->listdel), &iter);
    gtk_list_store_set (GTK_LIST_STORE(widgets->listdel),&iter,0,"2",1,"Name2",2,"Fmname2",3,"heute1",-1);
    gtk_list_store_append (GTK_LIST_STORE(widgets->listdel), &iter);
    gtk_list_store_set (GTK_LIST_STORE(widgets->listdel),&iter,0,"3",1,"Name3",2,"Fmname3",3,"heute2",-1);

    g_signal_connect(G_OBJECT(main_win), "draw",G_CALLBACK(gtk_widget_queue_draw),NULL);

    gtk_container_add(GTK_CONTAINER(main_win),GTK_WIDGET(widgets->box));


    gtk_builder_connect_signals(builder, widgets);
    g_object_unref(widgets->listdel);

    }
//funct for create new box
void on_btPatient_clicked(GtkWidget *widget, stMainwin *widgets){


    gtk_list_store_clear(widgets->listdel);
    gtk_widget_destroy(widgets->box);
    pat_win(widgets->main_win);

    }

其他盒子

void pat_win(GtkWidget *main_win){
    GtkBuilder *builder;
    GtkWidget *box;
    patient *ptwidgets = g_slice_new(patient);


    builder = gtk_builder_new();
    gtk_builder_add_from_file (builder, "/home/carlo/Nextcloud/FH/HWSE2/HWSE-Projekt/hwse/win_pat.glade", NULL);
    box = GTK_WIDGET(gtk_builder_get_object(builder,"pat_box"));
    gtk_container_add(GTK_CONTAINER(main_win),GTK_WIDGET(box));
    stMainwin *widgets = g_slice_new(stMainwin);
    widgets->main_win = main_win;
    widgets->box = box;
    //gtk_builder_connect_signals(builder, widgets);
    gtk_builder_connect_signals(builder, widgets);

    ptwidgets->txSvnr = GTK_WIDGET(gtk_builder_get_object(builder,"txSvnr"));
    ptwidgets->txName = GTK_WIDGET(gtk_builder_get_object(builder,"txName"));
    ptwidgets->txFmname = GTK_WIDGET(gtk_builder_get_object(builder,"txFmname"));
    ptwidgets->txGbdatum = GTK_WIDGET(gtk_builder_get_object(builder,"txGbdatum"));
    ptwidgets->txGbort = GTK_WIDGET(gtk_builder_get_object(builder,"txGbort"));
    ptwidgets->txAdresse = GTK_WIDGET(gtk_builder_get_object(builder,"txAdresse"));
    ptwidgets->txPlz = GTK_WIDGET(gtk_builder_get_object(builder,"txPlz"));
    ptwidgets->txStadt = GTK_WIDGET(gtk_builder_get_object(builder,"txStadt"));


    g_object_unref(builder);

    g_signal_connect(G_OBJECT(main_win), "draw",G_CALLBACK(gtk_widget_queue_draw),NULL);



}

void on_btBack_clicked(GtkWidget *widget, stMainwin *widgets){


    
    gtk_widget_destroy(widgets->box);
    widgets->box = NULL;
    main_box(widgets->main_win);


}

这些是 Glade 为 2 个盒子提供的 XML 文件:

**Main Box XML**

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface>
  <requires lib="gtk+" version="3.24"/>
  <object class="GtkBox" id="box">
    <property name="name">box</property>
    <property name="visible">True</property>
    <property name="can-focus">False</property>
    <property name="hexpand">True</property>
    <property name="vexpand">True</property>
    <property name="orientation">vertical</property>
    <property name="baseline-position">top</property>
    <child>
      <object class="GtkScrolledWindow" id="scroll">
        <property name="name">scroll</property>
        <property name="visible">True</property>
        <property name="can-focus">True</property>
        <property name="shadow-type">in</property>
        <property name="propagate-natural-width">True</property>
        <property name="propagate-natural-height">True</property>
        <child>
          <object class="GtkTreeView" id="trMain">
            <property name="name">trMain</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <child internal-child="selection">
              <object class="GtkTreeSelection"/>
            </child>
          </object>
        </child>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="position">0</property>
      </packing>
    </child>
    <child>
      <object class="GtkButtonBox">
        <property name="visible">True</property>
        <property name="can-focus">False</property>
        <property name="layout-style">start</property>
        <child>
          <object class="GtkButton" id="btPatient">
            <property name="label" translatable="yes">Patient</property>
            <property name="name">btPatient</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="receives-default">True</property>
            <signal name="clicked" handler="on_btPatient_clicked" swapped="no"/>
          </object>
          <packing>
            <property name="expand">True</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkButton" id="btResize">
            <property name="label" translatable="yes">resize</property>
            <property name="name">btResize</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="receives-default">True</property>
            <signal name="clicked" handler="on_btResize_clicked" swapped="no"/>
          </object>
          <packing>
            <property name="expand">True</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
        <child>
          <placeholder/>
        </child>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="pack-type">end</property>
        <property name="position">1</property>
      </packing>
    </child>
  </object>
  <object class="GtkListStore" id="liststore1"/>
  <object class="GtkListStore" id="liststore2"/>
</interface>

第二个框 XML:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface>
  <requires lib="gtk+" version="3.24"/>
  <object class="GtkBox" id="pat_box">
    <property name="visible">True</property>
    <property name="can-focus">False</property>
    <property name="margin-start">70</property>
    <property name="margin-top">100</property>
    <property name="margin-bottom">30</property>
    <property name="orientation">vertical</property>
    <child>
      <!-- n-columns=4 n-rows=8 -->
      <object class="GtkGrid">
        <property name="visible">True</property>
        <property name="can-focus">False</property>
        <property name="row-spacing">20</property>
        <property name="column-spacing">40</property>
        <child>
          <object class="GtkLabel">
            <property name="visible">True</property>
            <property name="can-focus">False</property>
            <property name="valign">baseline</property>
            <property name="margin-bottom">50</property>
            <property name="label" translatable="yes">SVNR</property>
            <property name="justify">right</property>
          </object>
          <packing>
            <property name="left-attach">0</property>
            <property name="top-attach">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkEntry" id="txSvnr">
            <property name="name">txSvnr</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="margin-bottom">50</property>
            <property name="max-length">10</property>
            <property name="width-chars">2</property>
            <property name="max-width-chars">2</property>
            <property name="input-purpose">number</property>
          </object>
          <packing>
            <property name="left-attach">1</property>
            <property name="top-attach">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel">
            <property name="visible">True</property>
            <property name="can-focus">False</property>
            <property name="label" translatable="yes">Vorname</property>
            <property name="justify">right</property>
          </object>
          <packing>
            <property name="left-attach">0</property>
            <property name="top-attach">1</property>
          </packing>
        </child>
        <child>
          <object class="GtkEntry" id="txName">
            <property name="name">txName</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="max-length">30</property>
            <property name="input-purpose">name</property>
          </object>
          <packing>
            <property name="left-attach">1</property>
            <property name="top-attach">1</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel">
            <property name="visible">True</property>
            <property name="can-focus">False</property>
            <property name="label" translatable="yes">Geburtsdatum</property>
          </object>
          <packing>
            <property name="left-attach">0</property>
            <property name="top-attach">3</property>
          </packing>
        </child>
        <child>
          <object class="GtkEntry" id="txGbdatum">
            <property name="name">TxGbdatum</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="input-purpose">digits</property>
          </object>
          <packing>
            <property name="left-attach">1</property>
            <property name="top-attach">3</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel">
            <property name="visible">True</property>
            <property name="can-focus">False</property>
            <property name="label" translatable="yes">Nachname</property>
          </object>
          <packing>
            <property name="left-attach">2</property>
            <property name="top-attach">1</property>
          </packing>
        </child>
        <child>
          <object class="GtkEntry" id="txFmname">
            <property name="name">txFmname</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="max-length">30</property>
            <property name="input-purpose">name</property>
          </object>
          <packing>
            <property name="left-attach">3</property>
            <property name="top-attach">1</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel">
            <property name="visible">True</property>
            <property name="can-focus">False</property>
            <property name="label" translatable="yes">Geburtsort</property>
          </object>
          <packing>
            <property name="left-attach">2</property>
            <property name="top-attach">3</property>
          </packing>
        </child>
        <child>
          <object class="GtkEntry" id="txGbort">
            <property name="name">txGbort</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
          </object>
          <packing>
            <property name="left-attach">3</property>
            <property name="top-attach">3</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel">
            <property name="visible">True</property>
            <property name="can-focus">False</property>
            <property name="label" translatable="yes">Adresse</property>
          </object>
          <packing>
            <property name="left-attach">0</property>
            <property name="top-attach">5</property>
          </packing>
        </child>
        <child>
          <object class="GtkEntry" id="txAdresse">
            <property name="name">txAdresse</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
          </object>
          <packing>
            <property name="left-attach">1</property>
            <property name="top-attach">5</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel">
            <property name="visible">True</property>
            <property name="can-focus">False</property>
            <property name="label" translatable="yes">PLZ</property>
          </object>
          <packing>
            <property name="left-attach">0</property>
            <property name="top-attach">7</property>
          </packing>
        </child>
        <child>
          <object class="GtkEntry" id="txPlz">
            <property name="name">txPlz</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
          </object>
          <packing>
            <property name="left-attach">1</property>
            <property name="top-attach">7</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel">
            <property name="visible">True</property>
            <property name="can-focus">False</property>
            <property name="label" translatable="yes">Stadt</property>
          </object>
          <packing>
            <property name="left-attach">2</property>
            <property name="top-attach">7</property>
          </packing>
        </child>
        <child>
          <object class="GtkEntry" id="txStadt">
            <property name="name">txStadt</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
          </object>
          <packing>
            <property name="left-attach">3</property>
            <property name="top-attach">7</property>
          </packing>
        </child>
        <child>
          <placeholder/>
        </child>
        <child>
          <placeholder/>
        </child>
        <child>
          <placeholder/>
        </child>
        <child>
          <placeholder/>
        </child>
        <child>
          <placeholder/>
        </child>
        <child>
          <placeholder/>
        </child>
        <child>
          <placeholder/>
        </child>
        <child>
          <placeholder/>
        </child>
        <child>
          <placeholder/>
        </child>
        <child>
          <placeholder/>
        </child>
        <child>
          <placeholder/>
        </child>
        <child>
          <placeholder/>
        </child>
        <child>
          <placeholder/>
        </child>
        <child>
          <placeholder/>
        </child>
        <child>
          <placeholder/>
        </child>
        <child>
          <placeholder/>
        </child>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="position">0</property>
      </packing>
    </child>
    <child>
      <!-- n-columns=2 n-rows=1 -->
      <object class="GtkGrid">
        <property name="visible">True</property>
        <property name="can-focus">False</property>
        <property name="valign">end</property>
        <property name="column-spacing">200</property>
        <child>
          <object class="GtkButtonBox">
            <property name="visible">True</property>
            <property name="can-focus">False</property>
            <property name="halign">start</property>
            <property name="orientation">vertical</property>
            <property name="layout-style">start</property>
            <child>
              <object class="GtkButton" id="btBack">
                <property name="label" translatable="yes">Zurück</property>
                <property name="name">btBack</property>
                <property name="width-request">130</property>
                <property name="height-request">45</property>
                <property name="visible">True</property>
                <property name="can-focus">True</property>
                <property name="receives-default">True</property>
                <signal name="clicked" handler="on_btBack_clicked" swapped="no"/>
              </object>
              <packing>
                <property name="expand">True</property>
                <property name="fill">True</property>
                <property name="position">0</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="left-attach">0</property>
            <property name="top-attach">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkButtonBox">
            <property name="visible">True</property>
            <property name="can-focus">False</property>
            <property name="halign">end</property>
            <property name="spacing">30</property>
            <property name="layout-style">end</property>
            <child>
              <object class="GtkButton" id="btClear">
                <property name="label" translatable="yes">Clear</property>
                <property name="name">btClear</property>
                <property name="width-request">130</property>
                <property name="height-request">45</property>
                <property name="visible">True</property>
                <property name="can-focus">True</property>
                <property name="receives-default">True</property>
              </object>
              <packing>
                <property name="expand">True</property>
                <property name="fill">True</property>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkButton" id="btSuchen">
                <property name="label" translatable="yes">Suchen</property>
                <property name="name">btSuchen</property>
                <property name="width-request">130</property>
                <property name="height-request">45</property>
                <property name="visible">True</property>
                <property name="can-focus">True</property>
                <property name="receives-default">True</property>
              </object>
              <packing>
                <property name="expand">True</property>
                <property name="fill">True</property>
                <property name="position">1</property>
              </packing>
            </child>
            <child>
              <object class="GtkButton" id="btAendern">
                <property name="label" translatable="yes">Aendern</property>
                <property name="name">btAendern</property>
                <property name="width-request">130</property>
                <property name="height-request">45</property>
                <property name="visible">True</property>
                <property name="can-focus">True</property>
                <property name="receives-default">True</property>
              </object>
              <packing>
                <property name="expand">True</property>
                <property name="fill">True</property>
                <property name="position">2</property>
              </packing>
            </child>
            <child>
              <object class="GtkButton" id="btSave">
                <property name="label" translatable="yes">Speichern</property>
                <property name="name">btSave</property>
                <property name="width-request">130</property>
                <property name="height-request">45</property>
                <property name="visible">True</property>
                <property name="can-focus">True</property>
                <property name="receives-default">True</property>
                <property name="halign">end</property>
                <signal name="clicked" handler="on_btSave_clicked" swapped="no"/>
              </object>
              <packing>
                <property name="expand">True</property>
                <property name="fill">True</property>
                <property name="position">3</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="left-attach">1</property>
            <property name="top-attach">0</property>
          </packing>
        </child>
      </object>
      <packing>
        <property name="expand">True</property>
        <property name="fill">True</property>
        <property name="pack-type">end</property>
        <property name="position">1</property>
      </packing>
    </child>
  </object>
</interface>

我最近两天都在为这个问题而战。我尝试了许多不同的解决方案,但除了 gtk_widget_queue_draw 没有任何帮助。在此之后的某个时候滚动窗口的大小是正确的,但几乎所有时间仍然是错误的。

我现在开始学习编码,这是我第一次在 Stackoverflow 中写问题。我希望我不要发布太多,你能理解我写的东西。

在此先感谢您的帮助。

标签: cgtk3glade

解决方案


推荐阅读