【QSS】QSSの理解を深めよう Subcontrol編 ①【PySide2】

python,qt,PySide,PySide2,QSS

皆さん、QSS Subcontrol(キュエスエス サブコントロール)はご存じでしょうか?そもそもPySideのQSSを触ったことのない方もいらっしゃるかもしれません
そんな方のためにもQSS(Qt Style Sheets キュートスタイルシート)をざっくり説明するとHTMLでも使われているスタイルシートを使って、細かくwidgetの見た目を設定することができる機能のことで、もう少し踏み込んで説明するとHTMLやXMLなどで文書の体裁や見栄えを表現するために使われるCSS(Cascading Style Sheets カスケーディングスタイルシート)を基に作られたウィジェットの外観をカスタマイズできる機能のことです
この機能については【QSS】QSSの理解を深めよう【PySide2】でざっくり説明しましたのでぜひお読みください

今回は【QSS】QSSの理解を深めよう【PySide2】で詳しく説明できなかったSubcontrol(サブコントロール)について説明していきます
私が公開していますUnPySideスタイルレシピ【UnPySide QSS recipes】ではそのSubcontrolを使用したデザインを公開していますがあくまでスタイルレシピ、コピペで実装できるを基に公開していますので詳しい説明は一切していません
今回はもう一歩踏み込んだ内容をお伝えできればと思いsubcontrolにフォーカスした内容で解説していきたいと思っています

しかし、SubControlに関しては内容が長くなってしまうため、2つに分けて解説していきます

今回はその1つ目になります


サブコントロールとはなにか

QSpinboxやQSliderなどの複雑なWidget(ウィジェット)は複数のパーツで構成されています
複数のパーツはウィジェットであったり論理的なコンポーネントだったりします
例えば、QComboBoxは、アイコンとテキストの2つのパーツで構成されています
テキストのスタイルだけでなく、アイコンに関連するスタイルも定義することができ、アイコンの部分は、QCheckBox::drop-downのサブコントロールです

SubcontrolのQSSは、ほとんどのウィジェットに似ていて、ボックスモデルもサポートしています。
色、背景、背景色、背景画像、ボーダー、パディング、マージン、幅、高さなどをカスタマイズすることができますし
また、Pseudo-State(擬似クラス)をサポートしています

サブコントロールの描画位置は、subcontrol-origin、subcontrol-positionで指定することができますがこれの二つについて説明する前にmarginとpaddingについて解説していきます

marginとpaddingの基礎知識

全ての要素は表示領域とその境界線、余白があり、この3つを合わせた領域のことをレクタングルと呼びます
レクタングルは共通して下の画像のような構造になっています。

まずレクタングルには要素の内容(テキストなど)を表示するための領域があり、これが図の赤い部分になります。

表示領域の周りにはボーダーと呼ばれる境界線があり、これはborderプロパティで表示できます。図の黄色の部分になります。

また境界線内側外側は余白をとることができ、ボーダー内側の余白をpadding、外側の余白をmarginと呼びます。

図だけではイメージしづらいと思いますので、実際のWeb上で境界線・padding・margin・表示領域がどの部分にあたるか操作できるDemoをリンクしていますので触ってみてください

margin

境界線の外側の余白を指定する際に使用します
余白は上下左右個別に指定することができ、値はpx指定や%指定が可能です

marginを指定するプロパティは複数用意されており、以下があります

marginプロパティの種類

marginプロパティのみ、半角スペースで区切ることで最大4つまで値を指定できます
指定した値の数とそれらの値がどう適用されるかは、以下のようになります

プロパティ 説明 指定可能な値の数
margin 上下左右のmarginを指定 1~4
margin-top 上のmarginを指定 1
margin-bottom 下のmarginを指定 1
margin-left 左のmarginを指定 1
margin-right 右のmarginを指定 1

marginプロパティ指定詳細

値の数 各値の適用箇所 指定例
1 上下左右 margin: 1em
2 上下 左右 margin: 5% 0
3 上 左右 下 margin: 10px 50px 20px
4 上 下 左 右 margin: 10px 50px 20px 0

marginプロパティで上下左右を一度に指定、margin-topプロパティなどによる個別指定、どちらを利用するかは自由です

padding

境界線の内側の余白を指定する際に使用します

こちらも同じく上下左右個別に指定することができ、値はpx指定や%指定が可能です

paddingプロパティの種類

基本的にmarginと同じで、paddingプロパティは半角スペースで区切ることで最大4つまで値を指定することができます

プロパティ 説明 指定可能な値の数
padding 上下左右のpaddingを指定 1~4
padding-top 上のpaddingを指定 1
padding-bottom 下のpaddingを指定 1
padding-left 左のpaddingを指定 1
padding-right 右のpaddingを指定 1

marginプロパティ指定詳細

値の数 各値の適用箇所 指定例
1 上下左右 padding: 1em
2 上下 左右 padding: 10% 0
3 上 左右 下 padding: 10px 50px 20px
4 上 下 左 右 padding: 10px 50px 30px 0

marginと同じくどのプロパティを利用するかは自由です

borderプロパティ

borderはCSSの一括指定プロパティで、要素の境界を設定できますが今回は割愛させていただきます
デモはリンクしておきますので遊んでみてください

サブコントロールの描画位置について

なんとなくmarginとpaddingについてわかってきたところで
subcontrol-origin、subcontrol-positionこの二つについて説明していきます
上のほうでちらっと書いた通り、subcontrol-originとsubcontrol-positionはサブコントロールの描画位置を指定することができます
これらの使い方について解説していきます

subcontrol-origin

subcontrol-originは親ウィジェットにサブコントロールを描画するための参照先を定義することができます
デフォルトでは、パディングに描画されています
親要素内のサブコントロールの原点となるものを指定します

subcontrol-origin プロパティ

subcontrol-origin プロパティは4種類あります プロパティ 説明
subcontrol-origin margin subcontrolをmarginに描画します
subcontrol-origin border subcontrolをborderに描画します
subcontrol-origin padding subcontrolをpaddingに描画します
subcontrol-origin content subcontrolをcontentに描画します

subcontrol-position

サブコントロールは、親ウィジェットのパディングなどの領域に描画されるということは先ほどの解説で何となく理解できたかと思いますがパディングなどの領域のどのポジションに描画したいのかを指定することができません
それを解決するのに使用するのがsubcontrol-positionになります
サブコントロールによって subcontrol-position のデフォルト値が異なります
例えば、QSliderのハンドルのデフォルト値は**center center**であり、QSpinBoxのup-buttonのデフォルト値は**right top**になります

subcontrol-position プロパティ

subcontrol-position は水平方向と垂直方向に位置を指定します

プロパティ
subcontrol-position horizontal vertical

subcontrol-position horizontal

水平方向の subcontrol-position には 3 つの値があります

プロパティ 説明
subcontrol-position left subcontrolを指定した領域の左側に描画します
subcontrol-position center subcontrolを指定した領域の真ん中に描画します
subcontrol-position right subcontrolを指定した領域の右側に描画します

垂直方向の subcontrol-position には 3 つの値があります

プロパティ 説明
subcontrol-position top subcontrolを指定した領域の上側に描画します
subcontrol-position center subcontrolを指定した領域の真ん中に描画します
subcontrol-position bottom subcontrolを指定した領域の下側に描画します

サブコントロールの位置をオフセットする

サブコントロールの位置を微調整するときtop,bottom,left,rightは役に立ちます
特に:hoverや:pressedなどのUXなどで役立ちます
一般的によく使われているのはtopとleftを使用してサブコントロールをオフセットしてマウスの操作を確認できるようにします
オフセットはsubcontrol-orign と subcontrol-position で決定される位置に対して相対的になります
top,bottom,left,rightのデフォルトの値は0です

QCheckBox::indicator {
    subcontrol-origin: margin;
    subcontrol-position: left center;
}
QCheckBox::indicator:hover {
    top: 3px;
    left: 3px;
}


以上がSubcontrolの機能の紹介でした
2回目の記事では【QSS】コピペで実装できるデザインQSpinBox 4種 【QSpinBox 】のCSSを基にSubcontrolを解説していきます

それではお楽しみに


参考
MDN WebDocs
translated-content