QSSの使い方!!

PySide(Qt)には、HTMLでも使われているスタイルシートを使って、細かくwidgetの見た目を設定することができます(*´ω`*)b

一般的にスタイルシートは、CSSと言われて拡張子にも「.css」が使われていますが、Qt界では「QSS」のようです。どちらも、基本的な考え方や文法は同じものです!

ウインドウの背景を変えてみる!

まずは、簡単な方法で背景色をMayaっぽいグレーにしてみましょう!

import sys
from PySide import QtGui

app = QtGui.QApplication(sys.argv)
window = QtGui.QMainWindow()
window.setWindowTitle('PySide Test')
window.resize(640, 480)
window.setStyleSheet('background-color: #444444;')
window.show()

sys.exit(app.exec_())

スタイルシートを適用しているのは、「window.setStyleSheet(‘background-color: #444444;’)」の部分になり、すべてのwidgetで「setStyleSheet」のメソッドを通してスタイルシートを設定できます!

ここでは、「background-color」を「#444444」に設定しています。「background-color」が背景色のプロパティ名で、「#444444」が設定する色の16進法の値です。

次は、以下の2つのMainWindowを表示するコードを観てみましょう。

import sys
from PySide import QtGui
 
app = QtGui.QApplication(sys.argv)
windowA = QtGui.QMainWindow()
windowA.setWindowTitle('WindowA')
windowA.resize(640, 480)
windowA.setStyleSheet('background-color: #444444;')
windowA.show()

windowB = QtGui.QMainWindow()
windowB.setWindowTitle('WindowB')
windowB.resize(640, 480)
windowB.show()
 
sys.exit(app.exec_())

windowAにはスタイルシートを設定し、windowBには設定をしていません。widgetの「setStyleSheet」を通して設定すると、設定されたwidget以外(子は含む)には影響しません。全体の見た目の調整には向かないのです。。。

個人的な意見ですが、コードとデザインはなるべく切り分けたいので、この方法で設定することは滅多にありません。

外部ファイルから設定する!

続いては、スタイルシートを別途ファイルに保存して、読み込んでみましょう!

まず以下のコードを「style.qss」として、Pythonファイルと同じディレクトリに保存します。

QMainWindow{
	background-color: #444444;
}

前回と異なり、少し装飾が増えましたね。

スタイルシートは、「影響範囲 { 設定 } 」という書式で書かれています。

上記の例では、影響範囲が「QMainWindow」で、「{」から「}」の中に書いたものが、「QMainWindow」に対する設定になります。同じように「QLineEdit」などと続けることで、複数のWidgetの設定をまとめて書けます!

続いて、Pythonの方を観てみましょう!

import sys
import os
from PySide import QtGui

try:
	styleFile = os.path.join(
					os.path.dirname(__file__),
					'style.qss'
					)
	with open(styleFile, 'r') as f:
		style = f.read()
except:
	style = ''
		
app = QtGui.QApplication(sys.argv)
app.setStyleSheet(style)

windowA = QtGui.QMainWindow()
windowA.setWindowTitle('WindowA')
windowA.resize(640, 480)
windowA.show()

windowB = QtGui.QMainWindow()
windowB.setWindowTitle('WindowB')
windowB.resize(640, 480)
windowB.show()
 
sys.exit(app.exec_())

急にコードが増えてしまいましたね、、、(;´∀`)

まず、「外部ファイルのパスを直接していすればOK」というわけでないので、ファイルの中身をすべて読み込んで設定してあげる必要があります。

読み込んだスタイルシートの文字列は、QApplicationの「setStyleSheet」から設定すると、全てのwidgetに効果を持ちます。

ボタンの色を変えてみる!

次は、QMainWindowにQPushButtonを追加して、ボタンの背景色と、文字の色を変えてみましょう!

まず、スタイルシートを以下のように修正します!

QMainWindow{
	background-color: #444444;
}

QPushButton{
	background-color: #5285a6;
	color: #bdbdbd;
}

「QPushButton{~~~}」を追加して、「QPushButton」の設定を追加します。

ボタンの背景色は、青系の色「#5285a6」に設定します。「color」は文字の色の設定で、すこしグレーがかった白「#bdbdbd」を設定しています。

続いて、Python側です。ちょっとコードが煩雑になってきたのでClassを使用します。

import sys
import os
from PySide import QtGui

class MainWindow(QtGui.QMainWindow):
	def __init__(self, *args, **kwargs):
		super(MainWindow, self).__init__(*args, **kwargs)
		self.setWindowTitle('WindowA')
		self.resize(640, 480)
		
		widget = QtGui.QWidget(self)
		self.setCentralWidget(widget)
		
		layout = QtGui.QVBoxLayout(widget)
		
		button = QtGui.QPushButton('Push Button', self)
		layout.addWidget(button)
	
if __name__ == '__main__':
	try:
		styleFile = os.path.join(
						os.path.dirname(__file__),
						'style.qss'
						)
		with open(styleFile, 'r') as f:
			style = f.read()
	except:
		style = ''
		print styleFile
			
	app = QtGui.QApplication(sys.argv)
	app.setStyleSheet(style)

	window = MainWindow()
	window.show()
	 
	sys.exit(app.exec_())

実行してみると、以下の様に青いボタンに、白い文字が書かれた見た目になります!

 

ワイルドカードによる指定

試しに、QLineEditを追加してみます。

QLineEditの設定はまったくしていないので、白い背景の黒い文字になってしまいます。ぜーんぶのwidgetを細かく設定しないといけないのー!?っと思った方もいらっしゃると思います・・・

しかし!そこは便利にできています!影響範囲の部分に「*」を使うとすべてのwidgetに影響させることができます!基本的な背景の色、文字の色などを設定すると便利です(*´ω`*)b

早速、以下のように修正してみます!

*{
	background-color: #444444;
	color: #bdbdbd;
}

QPushButton{
	background-color: #5285a6;
}

まず「*{~~~}」の部分で、すべてのWidgetの背景色と文字の色を設定しています。しかし次に、「QPushButton」の背景の設定が残っていますね。これは「オーバーライド(上書き)」というものです!

スタイルシートは、上の行から順番に読み込んで設定されていきます。もし重複した設定があった場合、新しい値に上書きされるんです!便利!(*´ω`*)

この状態で実行すると、こんな感じになります!

設定の追加

ちょっと「QLineEdit」の設定がイケてないですね・・・(;´∀`) せっかくですので、MayaっぽくQLineEditの見た目を、背景色をちょっと暗くして、枠線に丸みの設定を変更してみましょう!

*{
	background-color: #444444;
	color: #bdbdbd;
}

QPushButton{
	background-color: #5285a6;
}

QLineEdit{
	background-color: #2b2b2b;
	border-radius: 2px;
}

こちらで実行してみると、以下のようにになります!∠( ゚д゚)/

状態による設定の追加

よく見ると、QLineEditにフォーカスを当てても、Mayaみたいに青色の枠が表示されません。QtではWidgetの状態に応じた見た目の設定もできるので、早速追加してみましょう!

*{
	background-color: #444444;
	color: #bdbdbd;
}

QPushButton{
	background-color: #5285a6;
}

QLineEdit{
	background-color: #2b2b2b;
	border-radius: 2px;
}
QLineEdit:focus{
	border-width: 2px;
    border-style: solid;
    border-color: #5285a6;
}

「QLineEdit:focus」の項目が追加されました!「影響範囲」の後に「状態」を追加します。

ここでは、フォーカスがある時でしたが、他にもマウスカーソルが重なった時「hover」や、クリックされている時「pressed」などあります。

早速実行してみて、フォーカスをQLineEditにすると以下のようになります!

名前をつけて指定

ここまでは、Widgetごとの指定でしたが、時には、このQLineEditは違う見た目にしたい!などイレギュラーなケースもあるかと思います。そんな時に便利なのが名前の指定です!

まずは、Pythonの方から修正してみます。QLineEditを1つ追加して「setObjectName」で名前を「RedLineEdit」とつけました。ここでつけた名前は、後々スタイルシートでも使用します。

import sys
import os
from PySide import QtGui

class MainWindow(QtGui.QMainWindow):
	def __init__(self, *args, **kwargs):
		super(MainWindow, self).__init__(*args, **kwargs)
		self.setWindowTitle('WindowA')
		self.resize(640, 480)
		
		widget = QtGui.QWidget(self)
		self.setCentralWidget(widget)
		
		layout = QtGui.QVBoxLayout(widget)
		
		button = QtGui.QPushButton('Push Button', self)
		layout.addWidget(button)
		
		lineEdit = QtGui.QLineEdit(self)
		layout.addWidget(lineEdit)
		
		lineEdit = QtGui.QLineEdit(self)
		lineEdit.setObjectName('RedLineEdit')
		layout.addWidget(lineEdit)
		
	
if __name__ == '__main__':
	try:
		styleFile = os.path.join(
						os.path.dirname(__file__),
						'style.qss'
						)
		with open(styleFile, 'r') as f:
			style = f.read()
	except:
		style = ''
		print styleFile
			
	app = QtGui.QApplication(sys.argv)
	app.setStyleSheet(style)

	window = MainWindow()
	window.show()
	 
	sys.exit(app.exec_())

次に、「RedLineEdit」の設定を追加します。

*{
	background-color: #444444;
	color: #bdbdbd;
}

QPushButton{
	background-color: #5285a6;
}

QLineEdit{
	background-color: #2b2b2b;
	border-radius: 2px;
}
QLineEdit:focus{
	border-width: 2px;
    border-style: solid;
    border-color: #5285a6;
}

QLineEdit#RedLineEdit{
	background-color: #520000;
}

末尾の「QLineEdit#RedLineEdit{~~~}」が、名前をつけたQLineEditに対する設定です!指定した名前に「#」をつけて指定すればOKです!上書きしていない設定は、通常のQLineEditの設定に従います。

プロパティによる指定

今度は、自分で設定したプロパティーに応じて適用するスタイルを選ぶ方法です!ユーザーの入力が良くなかった場合の色など、状況に応じて変化させたい時に便利な指定方法です!

まずは、QLineEditを追加して、「setProperty」を使い、「warning」に「”true”」を設定します。設定した名前、値はなんでもOKですが、QSSでも使用します。

import sys
import os
from PySide import QtGui
 
class MainWindow(QtGui.QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)
        self.setWindowTitle('WindowA')
        self.resize(640, 480)
         
        widget = QtGui.QWidget(self)
        self.setCentralWidget(widget)
         
        layout = QtGui.QVBoxLayout(widget)
         
        button = QtGui.QPushButton('Push Button', self)
        layout.addWidget(button)
         
        lineEdit = QtGui.QLineEdit(self)
        layout.addWidget(lineEdit)
         
        lineEdit = QtGui.QLineEdit(self)
        lineEdit.setObjectName('RedLineEdit')
        layout.addWidget(lineEdit)
		
        lineEdit = QtGui.QLineEdit(self)
        lineEdit.setProperty('warning', "true")
        layout.addWidget(lineEdit)
         
     
if __name__ == '__main__':
    try:
        styleFile = os.path.join(
                        os.path.dirname(__file__),
                        'style.qss'
                        )
        with open(styleFile, 'r') as f:
            style = f.read()
    except:
        style = ''
        print styleFile
             
    app = QtGui.QApplication(sys.argv)
    app.setStyleSheet(style)
 
    window = MainWindow()
    window.show()
      
    sys.exit(app.exec_())

次にQSSの指定は、「影響範囲[プロパティ名=値{~~~}」という形で指定します。

*{
    background-color: #444444;
    color: #bdbdbd;
}
 
QPushButton{
    background-color: #5285a6;
}
 
QLineEdit{
    background-color: #2b2b2b;
    border-radius: 2px;
}
QLineEdit:focus{
    border-width: 2px;
    border-style: solid;
    border-color: #5285a6;
}
 
QLineEdit#RedLineEdit{
    background-color: #520000;
}

QLineEdit[warning="true"]{
    background-color: #dcce87;
}

MayaっぽいWarningメッセージのときの背景色になりました!(*´ω`*)b

最後に

書いていたら思っていたより長くなってしまいました、、、(;´∀`)

このスタイルシートをマスターすれば、かなーーーーーりオサレなUIを作る近道になります!オサレだけじゃなくて、ユーザーにとってもわかりやすいUIにするためにも不可欠です。

ここで紹介しきれなかったもの以外にも、たくさんのテクニックがあります。英語になってしまいますが、本家のヘルプに色々な例で指定方法が紹介されていますので、是非合わせてご覧いただければっと思います!(`・ω・´)ゞ

http://doc.qt.io/qt-4.8/stylesheet-examples.html