QSS 初体验

  • 类似css写好样式,然后给主窗体控件添加该样式即可
......
if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = WinForm()
    # 写好样式:这里添加了背景色和边框(为了体现效果,边框设置得很粗)
    qss_style = '''
        QPushButton {
            background-color: red;
            border: 10px solid purple;
        }
    
    '''
    # 应用样式
    win.setStyleSheet(qss_style)
    sys.exit(app.exec_())

QSS 选择器(参考CSS选择器的用法)

  • demo 演示: 改变特定按钮的样式
# -*- coding=utf-8
import sys
from PyQt5.QtWidgets import *

class QSSSelector(QWidget):

    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle('QSS选择器')

        btn1 = QPushButton(self)
        btn1.setText('按钮1') # 无属性值
        btn2 = QPushButton(self)
        btn2.setText('按钮2')
        btn2.setProperty('name','btn2') # 设置属性值,类似 name="btn2"
        btn3 = QPushButton(self)
        btn3.setText('按钮3')
        btn3.setProperty('name', 'btn3') # name="btn3"
 
        vbox = QVBoxLayout()
        vbox.addWidget(btn1)
        vbox.addWidget(btn2)
        vbox.addWidget(btn3)

        self.setLayout(vbox)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    main_window = QSSSelector()
    # 给 name=btn2 和 name=btn3 按钮设置样式
    qss_style = '''
        QPushButton[name="btn2"] {
            background-color: red;
            color: yellow;
            height: 120px;
            font-size: 60px;
        }
        QPushButton[name="btn3"] {
            background-color: red;
            color: yellow;
            height: 60px;
            font-size: 30px;
        }
    '''
    main_window.setStyleSheet(qss_style) # 渲染到窗体
    main_window.show()
    sys.exit(app.exec_())
  • 子控件选择器demo演示
# -*- coding=utf-8
import sys
from PyQt5.QtWidgets import *

class QSSSelector(QWidget):

    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle('QSS子控件选择器')

        combo = QComboBox(self)
        # 设置控件的名称: id="my_combo_box"
        combo.setObjectName('my_combo_box')
        combo.addItem('Window')
        combo.addItem('Linux')
        combo.addItem('Mac OS X')
        combo.move(50,50)

        self.setGeometry(250,200,320,150)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    main_window = QSSSelector()
    # 修改默认的下拉框图标样式
    qss_style = '''
        QComboBox#my_combo_box::drop-down {
            image:url(images/sohu.ico)
        }
    '''
    main_window.setStyleSheet(qss_style)
    main_window.show()
    sys.exit(app.exec_())
  • 设置窗体的样式demo演示

from PyQt5.QtCore import *
import sys
from PyQt5.QtWidgets import *


class WindowPattern(QMainWindow):
    def __init__(self):
        super().__init__()
        self.resize(500, 260)
        self.setWindowTitle('设置窗口的样式')
        # 设置窗口的样式 (hint暗示,示意)
        # 显示最大化按钮,窗口永远在最前端且无边框
        self.setWindowFlags(
            Qt.WindowMaximizeButtonHint | Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint) 
        # 设置窗口的名字
        self.setObjectName("MainWindow")
        # 背景图,后面会讲,设置语法类似CSS
        self.setStyleSheet("#MainWindow{border-image:url(images/1.png);}")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    form = WindowPattern()
    form.show()
    sys.exit(app.exec_())

控制窗口最大化和最小化

  • 窗体按钮会自带这个功能

  • 我们使用自定义按钮,也实现这个功能

# -*- coding=utf-8
'''
自定义按钮,实现窗体'最大化'和'最小化'
'''

from PyQt5.QtCore import *
import sys
from PyQt5.QtWidgets import *


class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.resize(300, 400)
        self.setWindowTitle('设置窗口的最大化和最小化')
        # 设置窗体自带'最大化'小按钮: 若单单只设置成这样,那么'最小化'和'打叉'都不能点击
        # self.setWindowFlags(Qt.WindowMaximizeButtonHint)

        max_btn = QPushButton(self)
        max_btn.setText('窗口最大化')
        max_btn.clicked.connect(self.maximum_size)


    def maximum_size(self):
        '''
        - 效果:除了系统底部菜单,窗体最大化(连窗体自带的'最大化'菜单栏都消失了,因为太大了)
        '''
        # 获取系统的桌面
        desktop = QApplication.desktop()
        # 获取桌面的可用尺寸(不包括系统底部菜单)
        rect = desktop.availableGeometry()
        # 设置尺寸
        self.setGeometry(rect)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    form = MainWindow()
    form.show()
    sys.exit(app.exec_())

  • 其实,qt内部已经封装了窗体'最大化'和'最小化'的方法,我们直接调用即可
# -*- coding=utf-8
'''
自定义按钮,实现窗体'最大化'和'最小化'

    - self.maximum_size

    - self.showMinimized
'''

from PyQt5.QtCore import *
import sys
from PyQt5.QtWidgets import *


class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.resize(300, 400)
        self.setWindowTitle('设置窗口的最大化和最小化')

        max_btn = QPushButton(self)
        max_btn.setText('窗口最大化')
        max_btn.setGeometry(50,50,100,100)
        # max_btn.clicked.connect(self.maximum_size)
        # 调用qt提供的方法
        max_btn.clicked.connect(self.showMaximized)

        min_btn = QPushButton(self)
        min_btn.setText('窗口最小化')
        # 调用qt提供的方法
        min_btn.clicked.connect(self.showMinimized)

......

实现不规则窗体(异形窗口)

  • 原理

    • 通过mask实现异形窗口

    • 需要提供一张透明的png图,把透明部分抠出,形成一个非矩形区域

# -*- coding=utf-8
'''
自定义按钮,实现窗体'最大化'和'最小化'
'''

from PyQt5.QtCore import *
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *


class AbnormityWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.setWindowTitle('异形窗口')
        self.pix = QBitmap('images/pretty.jpg')
        self.resize(self.pix.size())
        self.setMask(self.pix)

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.drawPixmap(0,0,self.pix.width(),self.pix.height(),QPixmap('images/pretty.jpg'))


if __name__ == "__main__":
    app = QApplication(sys.argv)
    form = AbnormityWindow()
    form.show()
    sys.exit(app.exec_())

加载gif图片,实现动画效果

# -*- coding=utf-8
'''
加载gif图片: QMovie
'''

from PyQt5.QtCore import *
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *


class GifWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.setWindowTitle('加载gif图片')
        self.label = QLabel('',self)
        self.setFixedSize(128,128)
        # 指定窗体样式
        self.setWindowFlags(Qt.Dialog | Qt.CustomizeWindowHint)
        # 加载gif图片
        self.movie = QMovie('../images/loading.gif')
        # 设置该图片并显示
        self.label.setMovie(self.movie)
        self.movie.start()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    form = GifWindow()
    form.show()
    sys.exit(app.exec_())

给控件添加背景图片

# -*- coding=utf-8

from PyQt5.QtCore import *
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *


class BackgroupWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.setWindowTitle('控件添加背景图片')
        label = QLabel(self)
        label.setToolTip('这是一个文本标签')
        # 加载背景图片
        label.setStyleSheet('QLabel{border-image:url(../images/pretty.jpg)}')
        label.setFixedWidth(476)
        label.setFixedHeight(259)

        btn = QPushButton(self)
        btn.setObjectName('btn')
        btn.setMaximumSize(48,48)
        btn.setMinimumSize(48,48)
        # 设置按钮图片
        style = '''
            #btn{
                border-radius:4px;
                background-image:url(../images/RED.ico)
            }
            #btn:Pressed{
                background-image:url(../images/sohu,ico)
            }
        '''

        btn.setStyleSheet(style)
        vbox = QVBoxLayout()
        vbox.addWidget(label)
        vbox.addWidget(btn)
        vbox.addStretch()

        self.setLayout(vbox)



if __name__ == "__main__":
    app = QApplication(sys.argv)
    form = BackgroupWindow()
    form.show()
    sys.exit(app.exec_())

图片的缩放

# -*- coding=utf-8
'''
图片缩放: QImage
'''

from PyQt5.QtCore import *
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *


class ScaleWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.setWindowTitle('图片缩放')
        filename = '../images/pretty.jpg'
        img = QImage(filename)
        label = QLabel(self)
        label.setFixedWidth(200)
        label.setFixedHeight(200)

        result = img.scaled(label.width(),label.height(),Qt.IgnoreAspectRatio,Qt.SmoothTransformation)
        label.setPixmap(QPixmap.fromImage(result))

        vbox = QVBoxLayout()
        vbox.addWidget(label)

        self.setLayout(vbox)



if __name__ == "__main__":
    app = QApplication(sys.argv)
    form = ScaleWindow()
    form.show()
    sys.exit(app.exec_())

创建透明窗体

# -*- coding=utf-8
'''
创建透明窗体: self.setWindowOpacity(0.5)
'''

from PyQt5.QtCore import *
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *


class BackgroupWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.setWindowOpacity(0.5)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    form = BackgroupWindow()
    form.show()
    sys.exit(app.exec_())

引入QSS文件

### 先写好 qss 文件
QLabel{
    border-image:url(../images/pretty.jpg)
}

### 新建一个专门读取 qss 文件的类
class QssFileHelper(object):
    @staticmethod
    def read_qss(style_file):
        with open(style_file,'r') as f:
            return f.read()

### 引入qss文件
'''
加载qss文件:
'''
from PyQt5.QtCore import *
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from CommonHelper import QssFileHelper


class QSSWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.setWindowTitle('加载qss文件')
        label = QLabel(self)
        label.setToolTip('这是一个文本标签')
        label.setFixedWidth(476)
        label.setFixedHeight(259)

        vbox = QVBoxLayout()
        vbox.addWidget(label)
        vbox.addStretch()

        self.setLayout(vbox)



if __name__ == "__main__":
    app = QApplication(sys.argv)
    form = QSSWindow()
    # 引入qss文件
    style_file = 'style.qss'
    # 读取qss文件内容
    qss_style = QssFileHelper.read_qss(style_file)
    # 设置样式
    form.setStyleSheet(qss_style)
    form.show()
    sys.exit(app.exec_())