分享

实战PyQt5: 105

 大傻子的文渊阁 2023-02-06 发布于浙江

在一个GUI应用中,缺省风格一般是和操作系统相统一的,但是有时候我们需要让应用有自己特定的风格,这时候我们就可以使Qt内建的各种主题样式来改变我们的应用程序外观。

设置应用显示风格

QWidget.setStyle(style:QStyle)函数可以设置应用的显示风格,要获取当前平台所支持的显示风格,可以使用QStyleFactory.keys()来获得,它以字符串列表的形式返回当前系统所支持的风格样式。使用方法QApplication.setStyle()可设置应用窗口的显示风格。如:

QApplication.setStyle(QStyleFactory.create('WindowsXP'))

如果一个QWidget未设置自己的显示风格,默认使用QApplication设置的风格。

Qt包含一组QStyle子类,这些子类可模拟Qt支持的不同平台的样式(QWindowsStyle,QMacStyle等)。默认情况下,这些样式内置在Qt GUI模块中。样式也可以作为插件使用。

Qt的内置窗口部件使用QStyle来执行几乎所有的绘图,从而确保它们看起来完全等同于等效的本机窗口小部件。下图显示了九种不同样式的QComboBox。

图片来源:doc.qt.io

Qt内建显示风格测试

测试代码采用了pyqt5中的styles.py,添加日历控件显示,演示各种控件在不同的显示风格下的外观。 完整代码如下:

import sys
from PyQt5.QtCore import Qt, QTimer, QDateTime, QDate
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import (QApplication, QWidget, QDialog, QPushButton, QTextEdit, 
                             QGroupBox, QCheckBox, QRadioButton, QComboBox, QLabel,
                             QVBoxLayout, QHBoxLayout, QGridLayout, QStyleFactory,
                             QTabWidget, QSizePolicy, QProgressBar, QTableWidget,
                             QLineEdit, QSpinBox, QDateTimeEdit, QSlider,
                             QScrollBar, QDial, QCalendarWidget)
 
#标记控制窗口
class WindowStyleDemo(QDialog):
    def __init__(self):
        super(WindowStyleDemo, self).__init__()
        
        # 设置窗口标题
        self.setWindowTitle('实战PyQt5: 应用显示风格演示')
        
        #应用的初始调色板
        self.origPalette = QApplication.palette()
        
        self.initUi()
        
    def initUi(self):
        styleComboBox = QComboBox()
        styleKeys = QStyleFactory.keys()
        print(styleKeys)
        #添加系统内建的显示风格
        styleComboBox.addItems(styleKeys)
        
        #最顶端显示控制部分
        styleLabel = QLabel('显示风格(&S):')
        styleLabel.setBuddy(styleComboBox)
        
        self.chkUseStylePalette = QCheckBox('使用标准调色板(&U)')
        self.chkUseStylePalette.setChecked(True)
        
        chkDisableWidgets = QCheckBox('禁用控件(&D)')
        
        #生成要显示的部件
        self.createTopLeftGroupBox()
        self.createTopRightGroupBox()
        self.createBottomLeftTabWidget()
        self.createBottomRightGroupBox()
        self.createProgressBar()
        
        styleComboBox.activated[str].connect(self.changeStyle)
        self.chkUseStylePalette.toggled.connect(self.changePalette)
        chkDisableWidgets.toggled.connect(self.setWidgetsDisbaled)
        
        topLayout = QHBoxLayout()
        topLayout.addWidget(styleLabel)
        topLayout.addWidget(styleComboBox)
        topLayout.addStretch(1)
        topLayout.addWidget(self.chkUseStylePalette)
        topLayout.addWidget(chkDisableWidgets)
        
        mainLayout = QGridLayout()
        mainLayout.addLayout(topLayout, 0, 0, 1, 2) # 0行0列,占1行2列
        mainLayout.addWidget(self.topLeftGroupBox, 1, 0) #1行0列
        mainLayout.addWidget(self.topRightGroupBox, 1, 1) #1行1列
        mainLayout.addWidget(self.bottomLeftTabWidget, 2, 0) #2行0列
        mainLayout.addWidget(self.bottomRightGroupBox, 2, 1) #2行1列
        mainLayout.addWidget(self.progressBar, 3, 0, 1, 2) ## 3行0列,占1行2列
        mainLayout.setRowStretch(1, 1)
        mainLayout.setRowStretch(2, 1)
        mainLayout.setColumnStretch(0, 1)
        mainLayout.setColumnStretch(1, 1)
        
        self.setLayout(mainLayout)
        
        #如果风格'Windows'存在,则将风格设置为'Windows'
        for index, style in  enumerate(styleKeys):
            if(style == 'Windows'):
                self.changeStyle('Windows')
                styleComboBox.setCurrentIndex(index)
        
    #改变显示风格 
    def changeStyle(self, styleName):
        QApplication.setStyle(QStyleFactory.create(styleName))
        self.changePalette()
        
    #改变调色板    
    def changePalette(self):
        if(self.chkUseStylePalette.isChecked()):
            QApplication.setPalette(QApplication.style().standardPalette())
        else:
            QApplication.setPalette(self.origPalette)
    
    #创建左上角成组部件
    def createTopLeftGroupBox(self):
        self.topLeftGroupBox = QGroupBox('组 1')
        
        rad1 = QRadioButton('单选按钮1')
        rad2 = QRadioButton('单选按钮2')
        rad3 = QRadioButton('单选按钮3')
        rad1.setChecked(True)
        
        chk = QCheckBox('三态复选按钮')
        chk.setTristate(True)
        chk.setCheckState(Qt.PartiallyChecked)
        
        layout = QVBoxLayout()
        layout.addWidget(rad1)
        layout.addWidget(rad2)
        layout.addWidget(rad3)
        layout.addWidget(chk)
        layout.addStretch(1)
        
        self.topLeftGroupBox.setLayout(layout)
        
    #创建右上角成组部件
    def createTopRightGroupBox(self):
        self.topRightGroupBox = QGroupBox('组 2')
        
        btnDefault = QPushButton('Push Button:缺省模式')
        btnDefault.setDefault(True)
        
        btnToggle = QPushButton('Push Button: 切换模式')
        btnToggle.setCheckable(True)
        btnToggle.setChecked(True)
        
        btnFlat = QPushButton('Push Button: 扁平外观')
        btnFlat.setFlat(True)
        
        layout = QVBoxLayout()
        layout.addWidget(btnDefault)
        layout.addWidget(btnToggle)
        layout.addWidget(btnFlat)
        layout.addStretch(1)
        
        self.topRightGroupBox.setLayout(layout)
        
    #创建左下角Tab控件
    def createBottomLeftTabWidget(self):
        self.bottomLeftTabWidget = QTabWidget()
        self.bottomLeftTabWidget.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Ignored)
        
        tab1 = QWidget()
        tableWidget = QTableWidget(10, 10)  #10行10列
        
        tab1Layout = QHBoxLayout()
        tab1Layout.setContentsMargins(5,5,5,5)
        tab1Layout.addWidget(tableWidget)
        tab1.setLayout(tab1Layout)
        
        tab2 = QWidget()
        textEdit = QTextEdit()
        textEdit.setPlainText("一闪一闪小星星,\n"
                              "我想知道你是什么.\n" 
                              "在整个世界之上, 如此的高,\n"
                              "像在天空中的钻石.\n"
                              "一闪一闪小星星,\n" 
                              "我多想知道你是什么!\n")
        
        tab2Layout = QHBoxLayout()
        tab2Layout.setContentsMargins(5, 5, 5, 5)
        tab2Layout.addWidget(textEdit)
        tab2.setLayout(tab2Layout)
        
        tab3 = QWidget()
        calendar = QCalendarWidget()
        #设置最小日期
        calendar.setMinimumDate(QDate(1900,1,1))
        #设置最大日期
        calendar.setMaximumDate(QDate(4046,1,1))
        #设置网格可见
        calendar.setGridVisible(True)
        tab3Layout = QHBoxLayout()
        tab3Layout.setContentsMargins(5, 5, 5, 5)
        tab3Layout.addWidget(calendar)
        tab3.setLayout(tab3Layout)
        
        self.bottomLeftTabWidget.addTab(tab1, '表格(&T)')
        self.bottomLeftTabWidget.addTab(tab2, '文本编辑(&E)')
        self.bottomLeftTabWidget.addTab(tab3, '日历(&C)')
         
    #创建又下角成组部件
    def createBottomRightGroupBox(self):
        self.bottomRightGroupBox = QGroupBox('组 3')
        self.bottomRightGroupBox.setCheckable(True)
        self.bottomRightGroupBox.setChecked(True)
        
        lineEdit = QLineEdit('s3cRe7')
        lineEdit.setEchoMode(QLineEdit.Password)
        
        spinBox = QSpinBox(self.bottomRightGroupBox)
        spinBox.setValue(50)
        
        dateTimeEdit = QDateTimeEdit(self.bottomRightGroupBox)
        dateTimeEdit.setDateTime(QDateTime.currentDateTime())
        
        slider = QSlider(Qt.Horizontal, self.bottomRightGroupBox)
        slider.setValue(40)
        
        scrollBar = QScrollBar(Qt.Horizontal, self.bottomRightGroupBox)
        scrollBar.setValue(60)
        
        dial = QDial(self.bottomRightGroupBox)
        dial.setValue(30)
        dial.setNotchesVisible(True)
        
        layout = QGridLayout()
        layout.addWidget(lineEdit, 0, 0, 1, 2)  #0行0列,占1行2列
        layout.addWidget(spinBox, 1, 0, 1, 2)   #1行0列,占1行2列
        layout.addWidget(dateTimeEdit, 2, 0, 1, 2) #2行0列,占1行2列
        layout.addWidget(slider, 3, 0)  #3行0列,占1行3列
        layout.addWidget(scrollBar, 4, 0) #4行0列,占1行1列
        layout.addWidget(dial, 3, 1, 2, 1)  #3行1列,占2行1列
        layout.setRowStretch(5, 1)
        
        self.bottomRightGroupBox.setLayout(layout)
        
    #禁止窗口上的组件
    def setWidgetsDisbaled(self, disable):
        self.topLeftGroupBox.setDisabled(disable)
        self.topRightGroupBox.setDisabled(disable)
        self.bottomLeftTabWidget.setDisabled(disable)
        self.bottomRightGroupBox.setDisabled(disable)
        
    #创建进度条
    def createProgressBar(self):
        self.progressBar = QProgressBar()
        self.progressBar.setRange(0, 10000)
        self.progressBar.setValue(0)
        
        # 定时器,定时更新进度条的值
        timer = QTimer(self)
        timer.timeout.connect(self.advanceProgressBar)
        timer.start(100)
        
    #设置进度条的值        
    def advanceProgressBar(self):
        curVal = self.progressBar.value()
        maxVal = self.progressBar.maximum()
        self.progressBar.setValue(curVal + (maxVal - curVal)//100)
 
    
if __name__ == '__main__':
    app = QApplication(sys.argv)
    windows = WindowStyleDemo()
    windows.show()
    sys.exit(app.exec())     

运行测试效果如下图:

应用显示风格测试

本文知识点

  • 设置应用的不同显示风格;
  • 设置系统调色板;
  • QGroupBox的setCheckable()功能;
  • 使用QTimer。

喜欢本文内容就多多关注,评论,收藏,点赞,和转发。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多