造型

Full-Stack-python / 2023-08-27 / 原文

使用 NodeGui,您可以根据需要设置小部件的样式。如果您熟悉网络世界中的CSS,您会感到宾至如归。所有小部件都有一个为相应小部件设置内联样式的方法。样式名称和值通常与 CSS 在 Web 上的工作方式相匹配。setInlineStyle

下面是一个示例:

const { QLabel, QMainWindow } = require("@nodegui/nodegui");

const win = new QMainWindow();

const label = new QLabel(win);
label.setText("Hello world");
label.setInlineStyle("color: green; background-color: white;");

win.show();
global.win = win;

概述#

NodeGui利用Qt的样式表进行样式设计。Qt样式表的术语和语法规则几乎与HTML CSS相同。此外,NodeGui 还增加了对使用 flex 属性(如对齐项、对齐内容等)布局的支持。Flexbox布局支持是使用Facebook的瑜伽库添加的。

您可以将样式属性写入字符串,并通过全局样式或内联样式(类似于它在 Web 中的工作方式)将其传递给 NodeGui 小部件。

全局样式#

让我们看一个例子:

const { QLabel, FlexLayout, QWidget } = require("@nodegui/nodegui");

const view = new QWidget();
view.setObjectName("rootView");
view.setLayout(new FlexLayout());

const label = new QLabel();
label.setObjectName("helloLabel");
label.setText("Hello");

const label2 = new QLabel();
label2.setObjectName("worldLabel");
label2.setText("World");

view.layout.addWidget(label);
view.layout.addWidget(label2);

view.setStyleSheet(`
  #helloLabel {
    color: red;
    padding: 10px;
  }
  #worldLabel {
    color: green;
    padding: 10px;
  }
  #rootView {
    background-color: black;
  }
`);
view.show();
(global as any).view = view;

对于全局样式表,您可以在样式表字符串中定义所有样式属性,并告诉根视图或窗口将其设置为其及其子小部件的样式表。这里与 web 的唯一区别是,您可以在整个小部件树中的任何级别上设置样式表,样式表将影响小部件及其子项。

在上面的例子中,为了引用样式表中的小部件,我们将使用 setObjectName 实例方法为其分配一个。将 objectName 视为类似于 web 的情况。现在使用 objectName,您可以在样式表中引用小部件并在其上设置样式属性。不要担心这里正在发生的布局问题,这将在下一节中介绍。objectNameid

当您使用伪选择器(悬停、选中等)之类的东西时,全局样式表确实变得强大。它还有助于实现级联样式,允许您一次设置一组小部件的样式。我们将在下面看到有关这些功能的更多信息。

有关所有功能和语法的更多详细信息,请参阅:https://doc.qt.io/qt-5/stylesheet-syntax.html

内联样式#

让我们再看一下这个例子:

const { QLabel, QMainWindow } = require("@nodegui/nodegui");

const win = new QMainWindow();

const label = new QLabel(win);
label.setText("Hello world");
label.setInlineStyle("color: green; background-color: white;");

win.show();
global.win = win;

在大多数情况下,内联样式小部件会更容易。NodeGui 支持使用实例方法进行内联样式。内联样式只会影响应用样式的小部件,并且通常更易于理解和管理。在全局样式表中使用的所有属性也都以内联样式提供。setInlineStyle

选择#

NodeGui 样式表支持 CSS2 中定义的所有选择器。 一些例子包括:

* {
  color: blue;
}

QPushButton {
  padding: 10px;
}

#okButton {
  margin: 10px;
}

#mainView > QPushButton {
  margin: 10px;
}

要查看选择器的完整列表,请参阅此处:https://doc.qt.io/qt-5/stylesheet-syntax.html#selector-types

伪状态#

就像在 Web 中一样,您可以根据小部件的状态设置其样式。例如,您可能希望按钮文本在悬停时的颜色为红色。这些对于伪状态是可能的。伪状态出现在选择器的末尾,带有冒号 (:)介于两者之间。

#okButton:hover {
  color: red;
}

级 联#

可以在父小部件和子小部件上设置样式表。任意小部件的有效样式表是通过合并小部件的祖先(父项、祖父项等)上设置的样式表来获得的。

当发生冲突时,无论冲突规则的特殊性如何,小部件自己的内联样式表始终优先于任何继承的样式表。同样,父小部件的样式表优先于祖项的样式表等。

这种行为类似于我们在网络上看到的行为。

有关更深入的示例,请参阅此处:https://doc.qt.io/qt-5/stylesheet-syntax.html#cascading

性能#

NodeGui 样式表是一个 css 字符串。

例如:

const textStyle = `
  color: 'green';
  padding: 12;
  height: '100%';
`;

在这里,如果你仔细观察,你会发现我们编写样式属性的方式与 web 相比存在一些差异。 你在周围看到的引号是必要的,这样Qt就不会将它们解释为数字。 因此,经验法则是,任何基于整数的属性(如边距、边框等)都可以在没有引号的情况下编写,而任何字符串属性最好用引号将它们括起来。PS:Qt确实可以识别一些没有引号的基于字符串的属性。'green''100%'

支持的属性#

由于我们不是在 Web 浏览器中运行的,因此您可以在 NodeGui 中使用的属性与在 Web 中使用的属性几乎没有区别。

完整列表详见:https://doc.qt.io/qt-5/stylesheet-reference.html#list-of-properties

除了链接中列出的属性外,NodeGui 还支持与 Flex 相关的布局属性。您可以在所有小部件上使用所有 flex 属性,例如对齐项目、两端对齐内容、flex 等。布局样式将在布局部分中更详细地转换。

高级用法(设置 QObject 属性)#

在Qt中,每个小部件都使用称为Q_PROPERTY的东西设置了某些属性。每个小部件上已经定义了许多 q 属性。您也可以自己在本机C++代码中定义自定义 qproperties。它与造型有什么关系?问题是其中一些属性可以使用qt样式表进行更改。在Qt的术语中,这些属性被称为可设计属性。

例如:

MyLabel {
  qproperty-alignment: AlignCenter;
}
MyGroupBox {
  qproperty-titlecolor: rgb(100, 200, 100);
}
QPushButton {
  qproperty-iconsize: 20px 20px;
}

您可以通过遵循Qt的文档或运行简单的Google搜索来发现这些属性,例如“使用Qt中的样式表在QLabel中居中文本”。这些是高级属性,在实践中很少使用,但很高兴知道。

更多详情 : https://doc.qt.io/qt-5/stylesheet-syntax.html#setting-qobject-properties


在本节中,我们主要介绍了 NodeGui 样式表中的绘制属性。下一节将介绍如何使用 flex 通过样式表布局小部件。