美文网首页
PySide2学习记录(十四):控件的风格和简单绘制

PySide2学习记录(十四):控件的风格和简单绘制

作者: 3ni | 来源:发表于2020-05-10 13:47 被阅读0次

    Python版本3.7
    PySide2 Version: 5.14.1
    官方文档:http://doc.qt.io/qtforpython/index.html

    QStyle类是一个抽象类,里面包含了各个控件的外观风格,由于这方面涉及到的东西太多,有些我也没有弄太懂,只能简单记录下。
    下面是关于QStyleFactory的使用,设置应用的风格,比如在Mac上实现windows风格。

    from PySide2.QtWidgets import QApplication, QWidget, QPushButton, \
        QVBoxLayout, QStyleFactory, QProgressBar
    
    app = QApplication()
    # 打印支持的风格
    print(QStyleFactory.keys())
    # 设置应用全局风格
    # app.setStyle(QStyleFactory.create('fusion'))
    
    window = QWidget()
    layout = QVBoxLayout()
    
    btn01 = QPushButton('111')
    btn02 = QPushButton('222')
    btn03 = QPushButton('333')
    progress = QProgressBar()
    
    # 设置单个控件风格
    btn02.setStyle(QStyleFactory.create('fusion'))
    btn03.setStyle(QStyleFactory.create('windows'))
    progress.setStyle(QStyleFactory.create('fusion'))
    
    progress.setValue(60)
    
    layout.addWidget(btn01)
    layout.addWidget(btn02)
    layout.addWidget(btn03)
    layout.addWidget(progress)
    
    window.setLayout(layout)
    window.show()
    app.exec_()
    

    运行截图:

    图1

    QStyleFactory是一个独立的类,即没有父类也没有子类,它只有两个静态函数,一个是create(arg_1),传入一个字符串参数,如上面例子中所示,还有一个是keys(),用来查看支持哪些风格。每个控件都可以单独设置自己的风格,也可以直接设置全局风格。
    如果不满意系统自带的风格,我们也可以自己绘制想要的风格,如下。

    from PySide2.QtWidgets import QPushButton, QApplication, QVBoxLayout, QWidget
    from PySide2.QtGui import QPainter, QColor, Qt, QPen
    
    class MyPushButton(QPushButton):
    
        def __init__(self, s, parent=None):
            super().__init__(s, parent)
            self.is_pressed = False
            self.is_entered = False
            
            # 鼠标按压事件
        def mousePressEvent(self, event):
            self.is_pressed = True
            self.update()
            
        # 鼠标释放事件
        def mouseReleaseEvent(self, event):
            self.is_pressed = False
            self.update()
            
        # 鼠标进入事件
        def enterEvent(self, event):
            self.is_entered = True
            self.update()
            
        # 鼠标离开事件
        def leaveEvent(self, event):
            self.is_entered = False
            self.update()
            
        # 绘图事件
        def paintEvent(self, event):
            painter = QPainter(self)
            # 获取绘制区域
            rect = self.rect()
            if self.is_entered:
                # 填充区域颜色
                painter.fillRect(rect, QColor("#B8B8B8"))
                if self.is_pressed:
                    painter.fillRect(rect, QColor("#FF0000"))
            else:
                painter.fillRect(rect, QColor("#E9E9E9"))
            # 绘制文本
            painter.drawText(rect, Qt.AlignCenter, self.text())
            pen = QPen(Qt.SolidLine)
            pen.setColor(QColor("#A9A9A9"))
            pen.setWidth(2)
            # 设置画笔
            painter.setPen(pen)
            # 绘制边框
            painter.drawRect(rect)
    
    
    app = QApplication()
    window = QWidget()
    layout = QVBoxLayout()
    
    btn = MyPushButton('我是按钮')
    default_btn = QPushButton('我是默认按钮')
    layout.addWidget(btn)
    layout.addWidget(default_btn)
    
    window.setLayout(layout)
    window.show()
    app.exec_()
    

    运行截图:

    图2

    除了像上面那样进行绘制之外,还有一种方式可以进行绘制。

    from PySide2.QtWidgets import QWidget, QPushButton, QApplication, \
        QVBoxLayout, QStyleOptionButton, QStyle
    from PySide2.QtGui import QPainter, QColor
    
    class MyPushButton(QPushButton):
        def __init__(self, s, parent=None):
            super().__init__(s, parent)
    
        def paintEvent(self, event):
            painter = QPainter(self)
            btn = QStyleOptionButton()
            btn.rect = self.rect()
            # adjusted用于对rect进行微调
            painter.fillRect(btn.rect.adjusted(7, 3, -7, -3), QColor("#FF6699"))
            btn.text = self.text()
            self.style().drawControl(QStyle.CE_PushButton, btn, painter)
    
    
    app = QApplication()
    window = QWidget()
    layout = QVBoxLayout()
    
    button01 = MyPushButton('按钮')
    button02 = QPushButton('默认按钮')
    layout.addWidget(button01)
    layout.addWidget(button02)
    
    window.setLayout(layout)
    window.show()
    app.exec_()
    
    

    上面例子使用了QStyleOptionButton这个类(其它类似的类请在官方文档查看),注意checkbox,radiobutton和pushbutton都属于button。QStyleOptionButton里面包含了要绘制这些按钮的所有信息,我们填充了好了QStyleOptionButton的对象之后,就可以使用QStyle类里面的drawControl方法来绘制这个控件,实际上这个方法主要用于绘制控制元素,主要是与用户交互或者显示一些信息的元素(详细请参考QStyle),比如按钮,单选框,进度条等等,其中QStyle.CE_PushButton代表了这个元素的样式,点击查看元素样式注意上面两个例子都是直接重新绘制控件的外观,如果我们想像第一个例子那样,使用函数setStyle()来设置来更改外观的话,需要自己继承QStyle类或者它的子类(一般情况下是继承子类),比如QCommonStyle类,然后将这个类的对象传递给setStyle函数,具体查看文档。下面提供一个例子仅供参考。

    from PySide2.QtWidgets import QApplication, QCommonStyle, QVBoxLayout, \
        QStyle, QWidget, QPushButton
    from PySide2.QtGui import QBrush, QColor
    from PySide2.QtCore import Qt
    
    class MyStyle(QCommonStyle):
        def __init__(self, text):
            super().__init__()
            self.text = text
    
        def drawControl(self, element, option, painter, w=None):
            default_color = QBrush(QColor('#FF6699'))
            enter_color = QBrush(QColor('#FF9900'))
            press_color = QBrush(QColor('#FF0000'))
    
            # 在c++中,这里直接可以强制转换成QStyleOptionButton,但是Python里面并不能
            pb = option
            area = pb.rect
    
            if pb.state & QStyle.State_MouseOver:
                painter.fillRect(area, default_color)
            elif pb.state & QStyle.State_Raised:
                painter.fillRect(area, enter_color)
            if pb.state & QStyle.State_Sunken:
                painter.fillRect(area, press_color)
            painter.drawText(area, Qt.AlignCenter, self.text)
    
        def polish(self, w):
            # 设置Qt::WA_Hover 属性后,将使鼠标在进入或离开部件时产生绘制事件
            w.setAttribute(Qt.WA_Hover, True)
    
        def unpolish(self, w):
            w.setAttribute(Qt.WA_Hover, False)
    
    
    app = QApplication()
    win = QWidget()
    layout = QVBoxLayout()
    
    btn01 = QPushButton('自定义style的按钮')
    btn02 = QPushButton('系统默认style的按钮')
    btn01.setStyle(MyStyle(btn01.text()))
    
    layout.addWidget(btn01)
    layout.addWidget(btn02)
    
    win.setLayout(layout)
    win.show()
    app.exec_()
    
    

    运行截图:

    图3

    友情链接:
    QStyleFactory
    QStyle
    Styles and Style Aware Widgets
    QStyleOptionButton

    相关文章

      网友评论

          本文标题:PySide2学习记录(十四):控件的风格和简单绘制

          本文链接:https://www.haomeiwen.com/subject/wtfjnhtx.html