自定义控件 - 补充1
画圆弧
调用 QPainter 对象的 drawArc 方法可以画一个圆弧,
drawArc 方法通常由6个参数,
前四个参数是 圆弧紧贴的外矩形的 左上角xy坐标 和 宽、高
后两个参数比较难的一些:分别是 圆弧的 起点角度 、 跨越角度
圆弧的 起点角度 是 从3点钟方向开始算起, 0 就代表 3点钟位置,
逆时针每加1度,数值 加16
顺时针每加1度,数值 减16
如果圆弧的起点是12点钟位置,可以是 90*16 , 也可以是 -270*16
最后一个参数 跨越角度 ,就是圆弧的从起点到终点的角度,
逆时针每加1度,数值 加16
顺时针每加1度,数值 减16
如下
from PySide2 import QtGui, QtWidgets
class MyWidget(QtWidgets.QWidget):
def paintEvent(self, e):
painter = QtGui.QPainter(self)
painter.drawRect(10, 10, 300, 300)
# 画圆弧,起点角度为 0度 ; 跨越90度
painter.drawArc(10, 10, 300, 300, 0, 90 * 16)
# 画笔颜色改为红色
pen = QtGui.QPen()
pen.setColor(QtGui.QColor('red'))
painter.setPen(pen)
# 画圆弧,起点角度为 90度 ; 跨越90度
painter.drawArc(10, 10, 300, 300, 90*16, 90 * 16)
# 画笔颜色改为蓝色
pen = QtGui.QPen()
pen.setColor(QtGui.QColor('blue'))
painter.setPen(pen)
# 画圆弧,起点角度为 -90度 ; 跨越90度
painter.drawArc(10, 10, 300, 300, -90*16, 90 * 16)
painter.end() # 结束绘制
app = QtWidgets.QApplication()
window = QtWidgets.QMainWindow()
window.resize(500, 500)
my = MyWidget(window)
my.move(0,0)
my.resize(500,500)
window.show()
app.exec_()
QPaintEvent 事件对象
QWidget 的 paintEvent 方法,被Qt框架调用时,会传入一个 QPaintEvent 对象
通过这个对象,我们可以得到当前控件绘制相关信息。
最常用的就是 这个对象的 rect() 方法
该方法返回一个 QtCore.QRect 类型的对象
QRect对象对应的就是当前控件的区域信息。
比如
width() 方法,就可以得到绘制区的宽度
height() 方法,就可以得到绘制区的宽度
def paintEvent(self, e):
rect = e.rect()
width = rect.width() # 绘制区的宽度
height = rect.height() # 绘制区的高度
事件响应
继承自 QWidget 的控件,都可以响应 QWidget 相关的事件
比如: 键盘按键、鼠标点击拖拽、鼠标滚轮事件 等等。
当这些事件发生在一个 QWidget控件上时,Qt就会查看这个控件有没有实现这些事件 对应的处理函数。 如果有,就会执行对应的函数。
这些函数就是,事件响应函数。具体可以参考官方文档
这里我们介绍一些常见的事件响应
鼠标点击
当我们鼠标按键(左键、右键等)点击 QWidget控件时,分别针对鼠标按钮按下和抬起, 会触发 两个鼠标事件,导致Qt调用两个该控件函数函数:
mousePressEvent 和 mouseReleaseEvent
通常我们只要实现其中一个,比如 mousePressEvent 函数,放入鼠标点击要做的事件处理代码即可。
比如
from PySide2 import QtGui, QtWidgets
class QOutlet(QtWidgets.QWidget):
def __init__(self,parent, color) -> None:
super().__init__(parent)
self.color = color
self.setMinimumSize(70, 70)
self.setMaximumSize(70, 70)
def paintEvent(self, e):
painter = QtGui.QPainter(self)
pen = QtGui.QPen()
pen.setWidth(1)
pen.setColor(QtGui.QColor(self.color))
painter.setPen(pen)
painter.drawRect(0, 0, 60, 60)
pen = QtGui.QPen()
pen.setWidth(3)
pen.setColor(QtGui.QColor(self.color))
painter.setPen(pen)
painter.drawLine(12,10,12,25)
painter.drawLine(30,10,30,25)
painter.drawLine(48,10,48,25)
painter.drawLine(10,35,20,50)
painter.drawLine(50,35,40,50)
painter.end()
# 实现插座控件点击事件处理
def mousePressEvent(self, e):
print("插座控件被点击了")
print("事件对象",e)
print(e.button()) # 点击的哪个鼠标按键
print(e.pos()) # 点击处相对于控件的坐标
print(e.windowPos()) # 点击处相对于窗口的坐标
app = QtWidgets.QApplication()
window = QtWidgets.QMainWindow()
window.resize(500, 500)
my = QOutlet(window,'green')
my.move(10,10)
window.show()
app.exec_()
可以发现,mousePressEvent 有一个参数e,是当前发生的: 鼠标事件对象
所有的事件处理函数,都会接收一个事件对象参数, 这个事件对象,包含了事件的一些信息。
可以通过事件对象的方法(比如 上例中的button()、pos()等 )获取这些信息。
鼠标进入、离开
当 鼠标进入、离开 QWidget控件的 范围时,会分别触发对 enterEvent 和 leaveEvent 方法的调用
比如,可以在上面的控件代码中,添加如下两个方法
def enterEvent(self, e) :
print("进入我的范围")
def leaveEvent(self, e) :
print("离开我的范围")
这两个方法,通常可以用来实现 鼠标悬浮在控件上出现显示效果的变化。
比如 Qt的按钮控件,鼠标放在上面,底色会出现改变。
大家可以想一想具体怎么实现该功能
键盘按键
当,会分别触发对 keyPressEvent 和 keyReleaseEvent 方法的调用
并且传入响应的键盘事件对象。
通常我们只要实现其中一个,比如 mousePressEvent 函数,放入鼠标点击要做的事件处理代码即可。