实战PyQt5: 116-画刷类QBrush_pyqt5 qbrush_seniorwizard的博客-程序员秘密

技术标签: python  gui编程  qt  编码  pyside2  pyqt5  

QBrush简介

QBrush类定义由QPainter绘制的形状的填充图案。一个画刷可以有颜色,填充图案,渐变和纹理属性。

样式填充使用Qt.BrushStyle枚举变量定义填充图案。默认的填充样式为Qt.NoBrush,在这种样式下表示不填充所画的物体。标准填充样式为Qt.SolidPattern。可以在创建画刷对象是时候设置填充模式,也可以在创建对象后使用setSyle()函数来设置或者更改填充样式。下图显示了Qt中定义的填充模式

实战PyQt5: 116-画刷类QBrush

QBrush各种填充样式(图片来源:doc.qt.io)

color()定义填充图案的颜色,该颜色可以是Qt.GlobalColor中预定义的演示,也可以是其他任何QColor颜色。gradient()定义所使用的渐变填充样式, Qt提供了三种不同的渐变填充QLinearGradient,QConicalGradient和QRadialGradient。当填充模式使用Qt.TexturePattern时,则可以在创建画刷时提供像素图或者使用setTexture()来创建具有纹理填充功能的画刷。

注意:无论先前设置了什么样的填充模式,如果使用了setTexture(),都会使填充模式变成Qt.TexturePattern。如果填充模式我渐变,则setColor函数不起作用。

QBrush定义常用函数:

  • setColor():更改当前设置的颜色。
  • color(): 获得当前设置的颜色。
  • gradient():获得画刷的渐变设置。
  • setColor(): 将画刷的颜色设置为指定的颜色。
  • color(): 获得画刷的颜色。
  • setStyle(): 设置画刷的填充样式。
  • style(): 获得画刷的填充样式。
  • setTexture(): 设置画刷的纹理填充图像,同时将画刷的填充样式设置为Qt.TexturePattern。
  • texture(): 返回纹理图像。
  • setTransform(): 设置画刷的变换矩阵。画刷的变换矩阵与QPainter的变换矩阵合并产生最终的绘制效果。
  • tansform(): 返回画刷的当前变换矩阵。

测试

测试代码演示了如何使用画刷的各种填充模式,包括,颜色,样式,渐变,纹理等各种属性的演示。完整代码如下:

import sys, math
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt, QPoint, QPointF
from PyQt5.QtGui import (QColor,QPen, QPainter, QPainterPath, QPolygonF, QBrush, 
                         QLinearGradient, QConicalGradient, QRadialGradient, QGradient,
                         QPixmap)
from PyQt5.QtWidgets import (QApplication, QWidget, QHBoxLayout, QFormLayout, 
                             QLabel, QFrame, QSizePolicy, QSpinBox, QPushButton,
                             QColorDialog, QComboBox, QFileDialog)
 
class MyFrame(QFrame):
    def __init__(self, parent = None):
        super(MyFrame, self).__init__(parent)
        self.setFrameShape(QFrame.Box)
        self.setFrameShadow(QFrame.Plain)
        self.setLineWidth(1)
        self.setMidLineWidth(0)
        self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        
        self.brushColor = Qt.black
        self.pattern = Qt.SolidPattern
        self.filename = ''
        
    def setBrushColor(self, color):
        self.brushColor = color
        self.update()
        
    def setPattern(self, pattern):
        self.pattern = pattern
        self.update()
                
    def setTexture(self, filename):
        self.pattern = Qt.TexturePattern
        self.filename = filename
        self.update()
        
    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing, True)
        
        #绘制边框线
        painter.drawRect(self.rect())
        
        pen = QPen()
        pen.setColor(Qt.darkBlue)
        painter.setPen(pen)
        
        brush = QBrush()
        brush.setColor(self.brushColor)
        
        if self.pattern == Qt.TexturePattern:
            brush.setTexture(QPixmap(self.filename))
        elif self.pattern == Qt.LinearGradientPattern:
            lg = QLinearGradient(0, 0, 100, 0)
            lg.setColorAt(0, Qt.red)
            #lg.setSpread(QGradient.RepeatSpread)
            lg.setColorAt(1, Qt.blue)
            brush = QBrush(lg)          
        elif self.pattern == Qt.RadialGradientPattern:
            rg = QRadialGradient(50, 50, 200, 100, 100)
            rg.setColorAt(0, Qt.red)
            rg.setColorAt(1, Qt.blue)
            rg.setSpread(QGradient.RepeatSpread)
            brush = QBrush(rg)  
        elif self.pattern == Qt.ConicalGradientPattern:
            cg = QConicalGradient(100, 100, 120)
            cg.setColorAt(0, Qt.red)
            cg.setColorAt(1, Qt.blue)
            cg.setSpread(QGradient.RepeatSpread)
            brush = QBrush(cg)
        else:
            brush.setStyle(self.pattern)
 
        painter.setBrush(brush)   
        painter.drawRect(10, 10, 200, 160)
        painter.drawEllipse(300, 10, 160, 160)      
        painter.drawPie(10, 240, 240, 240, 30 * 16, 110 * 16)
        
        #绘制五角星
        #添加一个多边形(五角星)
        #外点:x=Rcos(72°*k)  y=Rsin(72°*k)   k=0,1,2,3,4
        #内点:r=Rsin18°/sin36°  x=rcos(72°*k+36°)  y=rsin(72°*k+36°)   k=0,1,2,3,4
        deg_18 = 18 * math.pi / 180
        deg_36 = 36 * math.pi / 180
        deg_72 = 72 * math.pi / 180
        r_out = 100 #半径
        r_inner = r_out * math.sin(deg_18) / math.sin(deg_36)
        polygon = QPolygonF()
        for i in range (5) :   
            #外点
            out_angle = deg_72 * i - deg_18   
            polygon.append(QPointF(r_out * math.cos(out_angle), r_out * math.sin(out_angle))) 
            #内点
            in_angle =  deg_72 * i + deg_18
            polygon.append(QPointF(r_inner * math.cos(in_angle), r_inner * math.sin(in_angle)))
        
        painter.translate(380, 280)
        painter.drawPolygon(polygon, Qt.WindingFill)
        
        
class DemoBrush(QWidget):
    def __init__(self, parent=None):
        super(DemoBrush, self).__init__(parent)   
        
        # 设置窗口标题
        self.setWindowTitle('实战PyQt5: QBrush演示') 
        
        #设置尺寸
        self.resize(720, 400)    
              
        self.initUi()
        
    def initUi(self):
        layout = QHBoxLayout()
        
        self.canvas = MyFrame()
        
        #颜色设置
        btnSetColor = QPushButton('设置颜色')
        btnSetColor.clicked.connect(self.onSetBrushColor)
        
        #填充模式
        cmbBrusStyle = QComboBox()
        cmbBrusStyle.addItems(['NoBrush', 'SolidPattern', 'Dense1Pattern', 'Dense2Pattern', 
                               'Dense3Pattern', 'Dense4Pattern','Dense5Pattern','Dense6Pattern',
                               'Dense7Pattern', 'HorPattern', 'VerPattern', 'CrossPattern',
                               'BDiagPattern', 'FDiagPattern', 'DiagCrossPattern'])
        cmbBrusStyle.currentTextChanged.connect(self.onBrushStyleChanged)
        cmbBrusStyle.setCurrentIndex(1)
        
        #渐变
        cmbGradient = QComboBox()
        cmbGradient.addItems(['None', 'LinearGradientPattern', 'RadialGradientPattern', 'ConicalGradientPattern'])
        cmbGradient.currentTextChanged.connect(self.onGradientChanged)
        
        #纹理
        btnTexture = QPushButton('打开图像文件')
        btnTexture.clicked.connect(self.onButtonTextureClicked)
        
        fLayout = QFormLayout()
        fLayout.setContentsMargins(0,0,0,0)
        fLayout.addRow('颜色: ', btnSetColor)
        fLayout.addRow('填充模式: ', cmbBrusStyle)
        fLayout.addRow('渐变: ', cmbGradient)
        fLayout.addRow('纹理: ', btnTexture)
        
        wid_left = QWidget()
        wid_left.setMaximumWidth(200)
        wid_left.setLayout(fLayout)
                  
        layout.addWidget(wid_left)
        layout.addWidget(self.canvas)
        
        self.setLayout(layout)
        
    def onSetBrushColor(self):
       color = QColorDialog.getColor()
       self.canvas.setBrushColor(color)
       
    def onBrushStyleChanged(self, style):
        if style == 'SolidPattern':
            self.canvas.setPattern(Qt.SolidPattern)
        elif style == 'Dense1Pattern':
            self.canvas.setPattern(Qt.Dense1Pattern)
        elif style == 'Dense2Pattern':
            self.canvas.setPattern(Qt.Dense2Pattern)
        elif style == 'Dense3Pattern':
            self.canvas.setPattern(Qt.Dense3Pattern)
        elif style == 'Dense4Pattern':
            self.canvas.setPattern(Qt.Dense4Pattern)
        elif style == 'Dense5Pattern':
            self.canvas.setPattern(Qt.Dense5Pattern)
        elif style == 'Dense6Pattern':
            self.canvas.setPattern(Qt.Dense6Pattern)
        elif style == 'Dense7Pattern':
            self.canvas.setPattern(Qt.Dense7Pattern)
        elif style == 'HorPattern':
            self.canvas.setPattern(Qt.HorPattern)
        elif style == 'VerPattern':
            self.canvas.setPattern(Qt.VerPattern)
        elif style == 'CrossPattern':
            self.canvas.setPattern(Qt.CrossPattern)
        elif style == 'BDiagPattern':
            self.canvas.setPattern(Qt.BDiagPattern)
        elif style == 'FDiagPattern':
            self.canvas.setPattern(Qt.FDiagPattern)
        elif style == 'DiagCrossPattern':
            self.canvas.setPattern(Qt.DiagCrossPattern)
        else:
            self.canvas.setPattern(Qt.NoBrush)
            
    def onGradientChanged(self, style):
        if style == 'LinearGradientPattern':
            self.canvas.setPattern(Qt.LinearGradientPattern)
        elif style == 'RadialGradientPattern':
            self.canvas.setPattern(Qt.RadialGradientPattern)
        elif style == 'ConicalGradientPattern':
            self.canvas.setPattern(Qt.ConicalGradientPattern)
        else:
            self.canvas.setPattern(Qt.NoBrush)
            
    def onButtonTextureClicked(self):
        path,_ = QFileDialog.getOpenFileName(self, '打开图像文件', '', '图像文件 (*.png)')
        
        if path:
            self.canvas.setTexture(path)
            
    
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = DemoBrush()
    window.show()
    sys.exit(app.exec())

运行结果如下图:

实战PyQt5: 116-画刷类QBrush

QBrush演示

本文知识点

  • QBrush用于填充一个区域,QPen用于绘制一个区域的边框线
  • QBrush的填充样式
  • QGradient 渐变控制

前一篇: 实战PyQt5: 115-画笔类QPen

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/seniorwizard/article/details/111199672

智能推荐

【刷题】紫书第六章:数据结构基础(例题部分)_紫书数据结构例题_Little_Fall的博客-程序员秘密

还没写完,但上课实在写不了题,总结一下。总结map的operator[]操作会在目标元素不存在时新建一个元素,无副作用的检验元素是否存在应该使用map.count()跳过了本章指针建树与手动内存池的部分,以后再学。多组数据题,完全可以while(init()),init包括了初始化与读入工作。list.insert(iter,val),在iter左边插入,不改变iter,返回被插入位置...

科技新闻_每日一闻_珞喻小森林的博客-程序员秘密

内容提要:谷歌员工联名抗议谷歌正在秘密进行一个项目(代号:Dragonfly)-该项目准备为适应中国政府的审查与监管机制而对谷歌搜索引擎得到的结果进行修改后再呈现给中国用户。评论:个人感觉谷歌员工只是要求公司对其公开项目背景,让他们知道自己在做什么?希望谷歌尊重员工个人的偏好与道德选择,让其自己决定做还是不做这个项目,谷歌高智商的码农们也不是那么好欺骗的呀!强行把中国政府要求谷歌搜索引擎做...

yum install rz sz_mengxianhua的博客-程序员秘密

yum自动安装:yum install lrzsz手动安装方法如下:定制安装的linux可能没有把rzsz包安装到系统,这对用securecrt这样的windows工具传输文件特别不方便。为了使用这个方便的法门,可以手动安装之。1、 下载软件 rzsz-3.48.tar.gz。登录linux,用命令wget http://freeware.sgi.com/s

LVS NAT模式和DR模式的区别_linuxvfast的博客-程序员秘密

2019独角兽企业重金招聘Python工程师标准>>> ...

基于Linux+6818开发板实现普通电子相册翻页功能_基于粤嵌开发板的电子相册系统框图_佳佳鸽的博客-程序员秘密

更多资料请点击:我的目录本篇仅用于记录自己所学知识及应用,代码仍可优化,仅供参考,如果发现有错误的地方,尽管留言于我,谢谢。首先是外部进程传参,传进的是某目录文件的路径(绝对路径/相对路径)。接着打开目录文件,遍历目录内所有的文件,将后缀名为“.bmp”的普通文件全部找出来,并拼接保存它们的路径到双向循环链表里,一个节点存放一个bmp图片的路径。再通过触摸屏返回的坐标值进行逻辑判断,例如返回坐标值 < 400,触摸了左边的显示屏,我们应该让双向循环链表的当前节点 p 指向 p->prev节点

从“程序员转行卖烧饼”想到IT人创业_乱战狂歌的博客-程序员秘密

作者:杨中科,传智播客联合创始人、如鹏网发起人。现为传智播客教学总监。原帖:http://bbs.csdn.net/topics/390579896  我的一个朋友最近总在跟我念叨着“我不想做开发了,整天累死累活写程序,也攒不下几个钱。我想辞职搞点啥!”我问他:“你想搞点啥?”。他说:“搞啥都比做开发强,做个网站赚广告费,接私活……实在不行我去卖烧饼去,你没看到《网

随便推点

C# sleep 和wait的区别_卓月的博客-程序员秘密

sleep和wait都是使线程暂时停止执行的方法,但它们有很大的不同。1. sleep是线程类Thread 的方法,它是使当前线程暂时睡眠,可以放在任何位置。而wait,它是使当前线程暂时放弃对象的使用权进行等待,必须放在同步方法或同步块里。2.Sleep使用的时候,线程并不会放弃对象的使用权,即不会释放对象锁,所以在同步方法或同步块中使用sleep,一个线程访问时,其他的线程

数据仓库--事实表和维度表_事实表,不设置主键,最后两项是measure属性_大灰狼学编程的博客-程序员秘密

文章参考:https://blog.csdn.net/davidwang9527/article/details/255531171.数据仓库与操作型数据库的区别数据仓库的物理模型与常见的操作型数据库的物理模型有很大不同。最明显的区别是:操作型数据库主要是用来支撑即时操作,对数据库的性能和质量要求都比较高,为了防止“garbage in,garbage out”,通常设计操作型数据库的...

分布式之分布式事务、分布式锁、接口幂等性、分布式session_weixin_30550081的博客-程序员秘密

一、分布式session  session 是啥?浏览器有个 cookie,在一段时间内这个 cookie 都存在,然后每次发请求过来都带上一个特殊的jsessionid cookie,就根据这个东西,在服务端可以维护一个对应的 session 域,里面可以放点数据。  一般的话只要你没关掉浏览器,cookie 还在,那么对应的那个 session 就在,但是如果 cookie 没了,s...

蓝屏代码大全详解_散格-的博客-程序员秘密

完整的BSOD错误代码列表从STOP 0x1到STOP 0xC0000221一个死机(BSOD)的蓝屏,技术上称为一个STOP错误,若在Windows遭受了严重的错误,被迫“停”的问题。在任何Windows操作系统中都会出现BSOD错误,包括Windows 10,Windows 8,Windows 7,Windows Vista,Windows XP甚至Windows 98/95。由于蓝屏错误让您别无选择,只能重新启动,故障排除可能很困难。幸运的是,几乎每个STOP错误都包含一个基于十六进制的.

Kettle调用Java文件(Jar包)_kettle调用jar包传参_俊不见高堂明镜的博客-程序员秘密

Kettle的脚本–>Modified Java Script Value不仅可以写js代码来处理数据,也可利用这个组件调用已经写好的Jar文件。 第一步、准备java项目。 在IDE中新建java项目,并写好相应的处理逻辑。 将写好的java项目,导出成jar包,放到kettle的lib或者libext文件夹内(注意:项目内引用的jar包,若kettle中不存在,也要一并复制进去)。

QQ5.0列表滑动删除的简单实现_古隔空间i believe_纯洁小码农_z的博客-程序员秘密

自定义一个view 继承LinearLayout:代码:public class SwipeLayout extends LinearLayout { private ViewDragHelper viewDragHelper; private View contentView; private View actionView; private int

推荐文章

热门文章

相关标签