使用CSS提供程序的GTK4小部件自定义无法始终正常工作

kwvwclae  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(122)

为了了解GTK 3,我一直在构建一些小型的“原理证明”程序,而现在GTK 4的可用性有限,我也一直在尝试了解这个版本。在尝试迁移到GTK 4时,我使用CSS提供程序为GTK 3编写了一个显示两个具有不同属性的进度条的程序,并在GTK 4下重新构建了它。当我运行GTK 4版本的程序时,程序中的CSS覆盖被忽略,除非我将CSS提供程序上下文引入其中一个进度条的显示级别,但这会导致两个进度条显示相同的行为,而不是每个进度条都有唯一的行为,我为一个标签小部件添加了CSS提供者和上下文,这个覆盖起作用了,但有些则不然。这就好像在显示级别忽略了某些CSS提供程序覆盖。查看有关优先级的文档(例如,GTK_STYLE_PROVIDER_PRIORITY_APPLICATION)并测试各种优先级常量并没有产生任何影响。
显示代码的内容在这个叙述中会太长,所以我已经将GTK 3和GTK 4版本的代码上传到我的Github存储库沿着还上传了一个“pdf”文件,直观地说明了GTK 3和GTK 4之间的不同行为。如果您想自己查看和测试代码,请访问以下链接:
https://github.com/cschuls/GTK4_Mystery
我认为可以在显示级别使用“id#”属性添加特定于widget的CSS定制,但这似乎只是增加了不必要的复杂性,而这种做法在GTK 3中运行良好。
补充说明。
通过试验各种场景,我找到了一个解决方法,它提供了将不同的样式属性应用于每个进度条小部件的理想结果。对于这些小部件,我将它们各自的CSS提供程序数据添加到显示样式上下文,而不是尝试将CSS提供程序添加到每个小部件的上下文。如果您希望查看此解决方法,我在我的Github存储库中添加了一个包含源代码的“工作区”文件夹。
这为这个问题提供了一个很好的解决方案,但是它没有回答我的根本问题,即为什么在应用程序执行过程中没有对每个进度条小部件的CSS提供程序信息进行规定;然而,与小部件(如标签和按钮)关联的CSS提供程序信息的行为却与它们在GTK 3中的行为相同。如果有人能回答我的核心问题,我将非常高兴。
此致,
克雷格

eeq64g8w

eeq64g8w1#

因为这个问题有点老,一些使用的函数是“不推荐的”。这就是为什么我的答案基于当前的状态。
我做的第一件事是添加一个名为“css_resource. css”的CSS文件

#startbutton {
    background: grey; 
    color: blue;
    }

#prog1 trough {
    background-image: none;
    background-color: #ffffff; 
    min-height: 10px;
    border-radius: 0px; 
    box-shadow: none;
    }

#prog1 progress { 
    background-image: none; 
    background-color: #b3a472; 
    min-height: 10px; 
    border-radius: 0px; 
    box-shadow: none;
    }

#prog2 trough {
     background-image: none; 
     background-color: #ffffff; 
     min-height: 10px; 
     border-radius: 0px; 
     box-shadow: none;
     } 

#prog2 progress { 
    background-image: none; 
    background-color: #92b372; 
    min-height: 10px; 
    border-radius: 0px; 
    box-shadow: none;
    }

字符串
我在文件“resource.xml”中也提到了这个文件。

<gresources>
    <gresource prefix="Prog">
            <file preprocess= "xml-stripblanks">progressbar.ui</file>
            <file>css_resource.css</file>
    </gresource> 
</gresources>


在progressbar.ui文件中,我给Button1起了一个名字。

<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.8.2 -->
<interface>
 <!-- interface-name progressbar.ui -->
<requires lib="gtk" version="4.0"/>
<object class="GtkWindow" id="window">
<property name="title">Progress Bar GTK4</property>
<child>
  <object class="GtkGrid" id="grid">
    <property name="halign">center</property>
    <property name="height-request">12</property>
    <property name="row-homogeneous">True</property>
    <property name="valign">center</property>
    <child>
      <object class="GtkProgressBar" id="progressbar1">
        <property name="name">prog1</property>
        <property name="halign">start</property>
        <property name="height-request">12</property>
        <property name="valign">center</property>
        <layout>
          <property name="column">0</property>
          <property name="column-span">2</property>
          <property name="row">0</property>
        </layout>
      </object>
    </child>
    <child>
      <object class="GtkProgressBar" id="progressbar2">
        <property name="name">prog2</property>
        <property name="height-request">12</property>
        <property name="valign">center</property>
        <layout>
          <property name="column">0</property>
          <property name="column-span">2</property>
          <property name="row">1</property>
        </layout>
      </object>
    </child>
    <child>
      <object class="GtkButton" id="button1">
    <property name="name">startbutton</property>      
        <property name="halign">start</property>
        <property name="label">Start</property>
        <property name="margin-end">7</property>
        <property name="margin-start">3</property>
        <layout>
          <property name="column">1</property>
          <property name="column-span">1</property>
          <property name="row">2</property>
          <property name="row-span">1</property>
        </layout>
      </object>
    </child>
     </object>
    </child>
  </object>
</interface>


文件“main.c”看起来像这样。

#include <gtk/gtk.h>

GtkProgressBar  *progressbar1;
GtkProgressBar  *progressbar2;
GtkWidget       *timer;

gboolean        run_progress;
guint           beginning_value;
guint           ending_value;

gboolean timer_handler(GtkWidget *timer)
{
    if (run_progress)
{
    beginning_value++;
    gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(progressbar1), (gdouble) beginning_value/ending_value );
    gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(progressbar2), (gdouble) beginning_value/ending_value );

    if (beginning_value >= ending_value)
        run_progress = FALSE;
 }

return TRUE; // FALSE kills the timer
}

static void do_progress (GtkWidget *widget, gpointer data)
{
    beginning_value = 0;
    run_progress    = TRUE;
}

static void activate (GtkApplication* app, gpointer user_data)
{
    GtkBuilder      *builder;
    GtkCssProvider  *provider;
    GtkStyleContext *context;
    GtkWindow       *window;
    GtkButton       *button1;
    GdkDisplay      *display;

    beginning_value = 0;
    ending_value    = 100;

    /* Construct a GtkBuilder instance and load our UI description */

    builder      = gtk_builder_new ();

    gtk_builder_add_from_resource (builder, "/Prog/progressbar.ui", NULL);

    window       = GTK_WINDOW(gtk_builder_get_object (builder, "window")); 
    button1      = GTK_BUTTON(gtk_builder_get_object (builder, "button1"));
    progressbar1 = GTK_PROGRESS_BAR(gtk_builder_get_object (builder, "progressbar1"));
    progressbar2 = GTK_PROGRESS_BAR(gtk_builder_get_object (builder, "progressbar2"));

    gtk_window_set_application (window, app);
    gtk_window_set_default_size (window, 400, 200);

    /* Connect signal handlers to the constructed widgets. */

    g_signal_connect (button1, "clicked", G_CALLBACK (do_progress), NULL);

    // create a css-provider and load from resource
    provider =gtk_css_provider_new();
    gtk_css_provider_load_from_resource(provider,"Prog/css_resource.css");

    // add the css-provider to the Display 
    gtk_style_context_add_provider_for_display(gdk_display_get_default(),
        GTK_STYLE_PROVIDER(provider),
        GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); 

    gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(progressbar1), (gdouble) 0.00);
    gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(progressbar2), (gdouble) 0.00);

    g_timeout_add(40, (GSourceFunc) timer_handler, timer);

    gtk_widget_set_visible (GTK_WIDGET(window),TRUE);
}

int main (int argc, char **argv)
{
    GtkApplication *app;
    int status;

    app = gtk_application_new ("local.craig.progressbar", G_APPLICATION_DEFAULT_FLAGS);
    g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
    status = g_application_run (G_APPLICATION (app), argc, argv);
    g_object_unref (app);

    return status;
}


“compile.script”文件保持不变。

#!/bin/bash

glib-compile-resources --target=ProgResource.c --generate-source resource.xml

gcc -Wno-format -o progressbar main.c ProgResource.c `pkg-config --cflags gtk4` `pkg-config --libs gtk4`

rm ProgResource.c


问候

相关问题