#PYTHON3 #QT #PYSISE2 #TUTORIAL #STYLE #FONT

PySide #12: 我還要更有型!StyleSheet, QFont, QFontDialog

一起創造我們的時尚

DekBan
Bucketing

--

Photo by Joshua Chun on Unsplash

繼上一篇的色彩篇,我們可以自由的選擇色彩,還可以修改主題的顏色,但我們想要更高的自由度,想想網頁設計的CSS能做出各種動畫效果,是不是很羨慕呢!在Qt中我們有如同HTML一般的XML UI檔,自然也能像CSS一樣修改畫面的各種屬性,那就是StyleSheet!

OverView

StyleSheet可以完成各種UI的設定與動作,如前景色、背景色甚至Hover效果,上次我們提到了顏色,而這次在重頭戲之前,先讓我們來了解字型的設定與自由選取吧!

QFont

在Qt中想要修改文字的字體,可以使用QFont來實作,實際上在之前的專案教學中也有使用到許多次,使用起來也跟QColor一樣非常簡單。

QFont中最主要的幾個參數,不外乎就是字體、大小、粗度以及斜體,毫無意外。

Declaration

from PySide2.QtGui import QFont# QFont(family, pointSize = -1, weight = -1, italic = false)
font = QFont("Arial", 20, QFont.Black , italic=True)

需要補充的事Weight這個參數,可以使用不同的粗度而非一般的粗體而已。

enum QFont::Weight

我們也可以設定每個字的間隔,包括letter以及word的Spacing,這也是常用的功能唷!

設定時必須選取Spacing的種類,不同種類會有不同的Spacing計算方式。

SpacingType
font.setLetterSpacing(QFont.AbsoluteSpacing, 5)
font.setWordSpacing(5.0)
Letter Spacing Demo
Word Spacing Demo

實際上,QFont還有許多諸如Style, Capitalization, Stretch等等較不常使用的設定參數,我們可以從官方的Document去做了解。

QFontDialog

QFontDialog的用法跟上一張的QColordialog使用起來非常相似,但是使用 getFont時要給予預設的字型或是原Widget所使用的字型,以便在使用者點擊Cancel時做回傳。

@QtCore.Slot()
def choose_font(self):
(ret, r_font) = QFontDialog().getFont(self._window.font(),
self._window,
'Get some font')
if ret:
print('select ok')
self._window.input_line.setText(r_font.__repr__())
else:
print('select cancelled')
QFontDialog Demo

StyleSheet

終於到了今天的主角啦!StyleSheet實際上就是QML檔案(ui檔內的語法)的style設計語法,就如同css之餘html一般。 StyleSheet有千千百百種設定,大概可以說個7 7 49天也不一定能說完,如同CSS一般博大精深。

但是!我們常用的其實也就是那幾個好用有實用的外觀設定了,諸如前景色、背景色、邊框、radius、hover等等效果都是常用的設定。而本篇我會介紹並且實作幾個常用到的物件以及其各種設定。

另外,StyleSheet會強制覆蓋掉Palette的屬性所以依同使用時要格外注意

其他詳細的StyleSheet請見: 官方文件

QLabel

QLabel據官方說法是不支援hover效果的,這使得他使用上更加簡單一些,而我們使用Label最在意的東西就只有三個,那就是邊框、圖片以及漸層!
其他,如邊框等等就比較沒有那麼的重要了。

Example :
使用線性梯度可以製造出漸層效果,除了直向的漸層以外也可以調整Xy的起始與結束點來調整角度,請帶入國中數學斜率公式

圖片可以使用 border-image:url()來做設定,但是要提醒的是,圖片會因為Label的長寬而自動填滿並延伸,要注意變形的問題唷!

最後,最簡單的邊角弧度是大部分的物件都有的屬性,單位是用 px來做設定。

QLabel{
border-radius: 5px;
background-color :
QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #ff5500, stop: 1 #0055ff);
border-image:url('./media/hot_article.png');
}
QLabel stylesheet

QPushButton

按鈕是變化最多端的物件了,可以設定的屬性也非常多唷!因為他有各種狀態,包含hover、click、press、release等等,所以相對可以設定的變化就更多樣了,讓我們一起來看看吧!

Example :
如同QLabel一般,按鈕也可以使用漸層、前景色及背景色,除此之外我們可以像在CSS中一樣,使用 來串接按鈕動作,並設定特定動作如hover、pressed時的stylesheet,這些動作通通都是分開的,因此所有屬性都能重新設定,包含顏色、字型、邊框等等。

button_style = """
QPushButton {
border: 2px solid #0033aa;
border-radius: 6px;
background-color: #00aaff;
color: #000000;

min-width: 80px;
}

QPushButton:hover {
color: #ffffff;
background-color:
QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1,
stop: 0 #000000, stop: 1 #00aaff);
}

QPushButton:pressed {
background-color: #FFA823;
color: #000000;
font: bold 14px;
}
ss_btn = self._window.stylesheet_btn
ss_btn.setText('Style Sheet')
ss_btn.setStyleSheet(button_style)
pushbutton stylesheet

QProgressBar

最後來教大家一個新的物件,同時也是我發現在官方教學上一個挺有趣的用法。 進度條,其實也是常用的功能之一,不過因為使用起來實在簡單所以就沒有在基礎物件中多做介紹。

ProgressBar最重要的函數就是 setValue()的SLOT,主要用來設定當前進度條的數值,並且可以用 valueChanged()這個Signal來monitor變化的過程並掛上其他的SLOT。

最後我們可以利用 reset()來重新設定ProgressBar的進度。

Declaration

建立兩個Slot 用於+10%跟reset

@QtCore.Slot()
def add_ten(self):
value = self._window.progress_bar.value()
if value < 90:
value += 10
else:
value = 100

self._window.progress_bar.setValue(value)

@QtCore.Slot()
def reset_progress(self):
self._window.progress_bar.reset()

串接各個按鈕,這邊用到lambda可見教學

# set progress bar
self._window.add_btn.clicked.connect(self.add_ten)
self._window.reset_btn.clicked.connect(self.reset_progress)
self._window.progress_bar.valueChanged.connect(
lambda v: self._window.output_text.append(str(v)))
QProgressBar Demo

StyleSheet

ProgressBar的style主要有兩個部分,包含外框、內條。

QProgressBar {
border: 2px solid #ee9933;
border-radius: 3px;
text-align: center;
}
QProgressBar:chunk {
background-color:
QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 0,
stop: 0 #000000, stop: 1 #00ff33);
width: 20px;
margin: 1px;
}

背景顏色同樣的是可以做漸層,另外 margin這個屬性可以調整給一個單位格之間的間隔,可以做出方格狀態的效果。

QProgressBar stylesheet demo

Source Code

完整代碼請看 : StyleSheet

結論

大家可能會發現現在開始會介紹比較多UI的設計方法,沒錯第十一章開始,會比較著重在前端的設計跟調整,讓大家可以對於畫面有更好的控制度,當然…我們目前不會介紹到openGL等3D的繪圖功能,後續也許會,但…且讓我回憶並K一下Document (XDD 。

我是夜海中的宅男DekBan,我們下次見,see ya next night.

Next Step: PySide #13: 視窗的一萬種樣子, QSystemTrayIcon, Frameless Window, MouseEvent

--

--

DekBan
Bucketing

เด็กบ้าน | 🌃夜裡溜搭的宅男,漂泊於月色鋪成的海