GTK+ 中的 CSS 过渡/动画。是不是可以?

Posted

技术标签:

【中文标题】GTK+ 中的 CSS 过渡/动画。是不是可以?【英文标题】:CSS transition/animation in GTK+. Is it possible?GTK+ 中的 CSS 过渡/动画。是否可以? 【发布时间】:2020-06-18 15:35:35 【问题描述】:

在 GTK+ 文档中,您可以阅读:

CSS 定义了一种机制,通过该机制可以使 CSS 属性值的更改逐渐生效,而不是一次性生效。 GTK+ 也支持这些转换。

所以我从昨天开始就一直在尝试在一个用 GTK 编写的应用程序中运行转换。不幸的是,我什至没有更进一步,因为文档中没有合理的示例。谁能告诉我如何在 GTK 应用程序中运行 CSS 过渡和动画?

编辑: 这是一个系统问题。我在虚拟机中在 openSUSE Leap 上运行了一个程序,一切正常。现在的问题是为什么它不能在 openSUSE Tumbleweed 上运行? 以下是我尝试运行的示例,但没有任何成功。

@keyframes spin 
   to  -gtk-icon-transform: rotate(1turn); 


spinner 
   animation-name: spin;
   animation-duration: 1s;
   animation-timing-function: linear;
   animation-iteration-count: infinite;


button 
  transition-property: width;
  transition-duration: 2s;
  transition-timing-function: linear;
  transition-delay: 1s;


button:hover 
  width: 300px;

这是林间空地文件:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.36.0 -->
<interface>
  <requires lib="gtk+" version="3.22"/>
  <object class="GtkWindow" id="main_window">
    <property name="name">main_window</property>
    <property name="can_focus">False</property>
    <child>
      <object class="GtkFixed" id="fixed">
        <property name="name">fixed</property>
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <child>
          <object class="GtkButton" id="button">
            <property name="label" translatable="yes">button</property>
            <property name="name">button</property>
            <property name="width_request">100</property>
            <property name="height_request">80</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
          </object>
          <packing>
            <property name="x">107</property>
            <property name="y">104</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel" id="label">
            <property name="name">label</property>
            <property name="width_request">100</property>
            <property name="height_request">80</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="label" translatable="yes">label</property>
          </object>
          <packing>
            <property name="x">107</property>
            <property name="y">17</property>
          </packing>
        </child>
        <child>
          <object class="GtkSpinner" id="spinner">
            <property name="name">spinner</property>
            <property name="width_request">100</property>
            <property name="height_request">80</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="active">True</property>
          </object>
          <packing>
            <property name="x">107</property>
            <property name="y">196</property>
          </packing>
        </child>
      </object>
    </child>
    <child type="titlebar">
      <placeholder/>
    </child>
  </object>
</interface>

和main.c


#include <gtk/gtk.h>
#include <stdlib.h>

GtkBuilder *builder;

// The highest level
GObject *main_window;
GObject *fixed;

// fixed level
GObject *label;
GObject *button;
GObject *spinner;


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

   gtk_init(&argc, &argv);
   builder = gtk_builder_new_from_file("../glade.glade");

   main_window = gtk_builder_get_object(builder, "main_window");
   fixed = gtk_builder_get_object(builder, "fixed");
   label = gtk_builder_get_object(builder, "label");
   button = gtk_builder_get_object(builder, "button");
   spinner = gtk_builder_get_object(builder, "spinner");

   // Build signal structure
   gtk_builder_connect_signals(builder, NULL);
   g_signal_connect(main_window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

   // Prepare css file
   GtkCssProvider *provider = gtk_css_provider_new();
   gtk_css_provider_load_from_path(
       provider, "../css.css", NULL);
   gtk_style_context_add_provider_for_screen(
       gdk_display_get_default_screen(gdk_display_get_default()),
       GTK_STYLE_PROVIDER(provider),
       GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);

   // Create window
   gtk_widget_show(GTK_WIDGET(main_window));
   gtk_main();

   return (EXIT_SUCCESS);

【问题讨论】:

您需要显示运行它的小部件树,即 C/Python/ui/whatever 文件...如果您没有在正确的小部件上运行它,它不会做任何事情.还要确保您的 GTK 版本与文档一致; CSS 过去在 3.x 的早期版本中完全不同,并且引用的语法应该只能从大约 3.20 开始可靠地使用。 我在主帖中添加了我使用的所有文件。文件树是扁平的:main.c、glade.glade、css.css。 pkg-config --modversion gtk+-3.0 --> 3.24.20 我刚刚测试了它在 Ubuntu 20.04 Mate 桌面中更正 min-with 属性。按钮转换不起作用。 gtk+-3.0 版本为3.24.20 【参考方案1】:

检查您的控制台。当我使用这 3 个文件构建和运行时,我看到了:

(a.exe:30940): Gtk-WARNING **: 17:10:50.844: Theme parsing error: test.css:20:7: 'width' is not a valid property name.

您可能想要min-width。通过用min-width 替换CSS 中对width 的两个引用来修复它之后,这和Spinner 都对我来说很好。我还检查了更改旋转动画持续时间是否有效。

【讨论】:

min-width,你是对的,这很奇怪,因为按钮现在变大了,但没有任何动画。并且微调器没有转动。也许有一些设置,必须打开?我的系统:openSUSE Tumbleweed VERSION="20200612" 这是一个 100% 的系统问题。我在虚拟机中在 openSUSE Leap 上运行了一个程序,一切正常。现在的问题是为什么它不能在 openSUSE Tumbleweed 上运行? 这似乎是 OpenSUSE 团队/跟踪者的问题。它可能与 VM 和/或其设置有关,因为我似乎记得动画有时会被禁用,但我认为做出该决定的将是环境,而不是 GTK 或代码。

以上是关于GTK+ 中的 CSS 过渡/动画。是不是可以?的主要内容,如果未能解决你的问题,请参考以下文章

vuebase-5.过渡和动画

09《Vue 入门教程》Vue 过渡 &amp;amp; 动画

Vue2.0学习—过渡与动画(六十三)

Vue动画操作

Vue学习之动画小结

vue2.0过度动画