【MayaPySide】QLinearGradientグラデーションを使う【PySide2】

python,qt,PySide,maya,PySide2

ある程度PySideに慣れてくるとちょっとアクセントとしてカラーを入れたり
ということをしていくと思います。
単色は簡単に設定できるのですがグラデーションってどうするのっていう壁にぶち当たります。
PySideのグラデーションはいろいろなやり方で表現できるのですがまたこれがまたややこしいのです
今回はQLinearGradientを使った方法を紹介したいと思います。
この記事では下のコードを使用していきます

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys

import maya.cmds as cmds
import pymel.core as pm
from maya import OpenMayaUI

from Qt.QtWidgets import *
from Qt.QtGui import *
from Qt.QtCore import *

try:
    import shiboken
except:
    import shiboken2 as shiboken

ptr = OpenMayaUI.MQtUtil.mainWindow()
parent = shiboken.wrapInstance(long(ptr), QWidget)

class Gui(QWidget):
    def __init__(self, *args, **kwargs):
        super(Gui, self).__init__(*args, **kwargs)
        self.initUI()

    def initUI(self):
        self.btn = QPushButton("qlineargradient", self)
        self.btn.setGeometry(50, 110, 200, 50)

        Label = ["x1", "y1", "x2", "y2"]
        self.Labels = []
        for i in range(len(Label)):
            self.Labels.append(QLabel(Label[i], self))
            self.Labels[i].setStyleSheet("""QLabel{
                color: #333333;
                font: 20px;
                font-family: Arial;
                }""")
            print i
            if i <= 1:
                self.Labels[i].move(20+235 * i , 80)
            else:
                self.Labels[i].move(20+235  * (i-2)  , 170)

class Example(QMainWindow):
    def __init__(self, *args, **kwargs):
        super(Example, self).__init__(parent, *args, **kwargs)
        self.initUI()

    def initUI(self):
        self.setCentralWidget(Gui())
        self.setAutoFillBackground(True)
        self.resize(300, 300)

def Example_UI():
    global Example_UI_ex
    app = QApplication.instance()
    Example_UI_ex = Example()
    Example_UI_ex.show()
    sys.exit()
    app.exec_()

Example_UI()

上のコードを実行すると下の画像のようなwindowが表示できるかと思います

widget内にあるX1、Y1、X2、Y2はQLinearGradientで設定するプロパティX1、Y1、X2、Y2のことで
それぞれの文字が対応する付近に配置しています
イメージ的には数学の授業とかで出てくる四角形を構成する点ABCDみたいな感じです。
それでは早速QLinerGradientを設定していきたいと思います。
今回はQPushButtonに対してsetStyleSheetに設定します
class Guiのdef initUI(self):内にあるself.btn.setGeometry(50, 110, 200, 50)の後に下のコードを記述します。

self.btn.setStyleSheet("""
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
stop:0 #009390, stop:0.5 #333333, stop:1.0 #FDD803);
""")

backgroundに対してqlineargradientを設定しており、グラデーションは始点(x1, y1)と終点(x2, y2)を結ぶラインに沿って形成され、ウィジェットの上が(0, 0)で下が(1, 1)になります
始点が(0, 0)で終点が(0, 1)の時は上から下の方向にグラデーションします
stopにはライン上の位置(0~1)と色をセットで指定します

上記のコードを記述して実行すると下のようなwindowが表示されます

次は左上から右下の方向にグラデーションさせてみましょう

self.btn.setStyleSheet("""
background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
stop:0 #009390, stop:0.5 #333333, stop:1.0 #FDD803);
""")

左上から右下の方向にグラデーションの場合は始点が(0, 0)で終点が(1, 1)になるため上のコードに変更して実行します。

うまく実行できると上の画像のように斜めにグラデーションがかかっています。
先ほど変更したコードのy2を1から0.5に変更して実行してみるとどうなるでしょう。

self.btn.setStyleSheet("""
background: qlineargradient(x1:0, y1:0, x2:1, y2:0.5,
stop:0 #009390, stop:0.5 #333333, stop:1.0 #FDD803);
""")


ちょっとおしゃれになりました
PySideのグラデーションはこのよううに座標に設定して表現することができます
一番最初の冒頭でいろいろなやり方で表現できるということを記述したかと思いますがせっかくですので次は別の方法でWidgetの背景に設定してみましょう
次の方法はQPaletteを使用します
class Exampleに新しくdef paletteUI(self):という関数を作ってみます。

    def paletteUI(self):
        setColors = ['#FDD803', '#333333']
        palette = QPalette()

関数を作りましたらdef initUI(self):にself.paletteUI()を記述して認識できるようにしてください。
setColorsには設定したい色を用意しておきます。
次にQLinearGradientを設定していきます。

gradient = QLinearGradient(QRectF(
                self.rect()).topLeft(),
                QRectF(self.rect()).bottomLeft()
            )
gradient.setColorAt(0.0, setColors[0])
gradient.setColorAt(1.0, setColors[1])
palette.setBrush(QPalette.Background, QBrush(gradient))
self.setPalette(palette)

QRectFsetColorAtでライン上の位置(0~1)と色をセットで指定し、QPalette()で描画します。
上のコードを記述し実行すると下の画像のような見た目に変更されます

グラデーションが使えるようになると表現の幅が大きく広がると思いますのでこれを機にぜひグラデーションを使ってみてはどうでしょうか