鼠标进出QLineEdit时更新QStyle调用drawPrimitive传参报错如何解决?
错误原因
drawPrimitive是Qt原生定义的虚函数,接口签名固定,不允许自行新增参数或传入未声明的关键字参数,你自定义方法时额外添加的a参数不符合Qt的接口规范,调用时传入a=self.a就会触发类型错误。
解决方法
不需要修改drawPrimitive的接口签名,调用该方法时会传入当前控件实例作为widget参数,直接从控件实例中读取你定义的状态属性即可,同时修复原有代码中缺少重绘触发、漏传参数、尺寸写死的问题。
修改后完整可运行代码:
from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import * import sys class LineEditStyle(QProxyStyle): # 保持原生drawPrimitive的参数签名不变 def drawPrimitive(self, element, option, painter, widget=None): # 从传入的widget参数直接读取悬停状态 border_color = 'green' if (widget and getattr(widget, 'hover_flag', 0)) else 'red' pen = QPen(QColor(border_color)) pen.setWidth(4) if element == QStyle.PE_FrameLineEdit: painter.setRenderHint(QPainter.Antialiasing) painter.setPen(pen) # 用option.rect适配控件实际尺寸,不要写死宽高 painter.drawRoundedRect(option.rect.adjusted(0,0,-1,-1), 10, 10) else: super().drawPrimitive(element, option, painter, widget) class LineEdit(QLineEdit): def __init__(self,*args,**kwargs): super().__init__(*args,**kwargs) self.hover_flag = 0 def enterEvent(self, a0): self.hover_flag = 1 self.update() # 修改状态后触发重绘 super().enterEvent(a0) def leaveEvent(self, a0): self.hover_flag = 0 self.update() # 修改状态后触发重绘 super().leaveEvent(a0) def paintEvent(self,event): # 先绘制原生输入框的文本、光标等内容 super().paintEvent(event) # 再绘制自定义边框 option = QStyleOption() option.initFrom(self) # 补齐drawPrimitive需要的所有参数:painter、当前控件实例 self.style().drawPrimitive(QStyle.PE_FrameLineEdit, option, self.painter(), self) if __name__ == '__main__': app = QApplication(sys.argv) window = QMainWindow() window.setGeometry(500,500,400,400) window.setStyleSheet('background-color:#373737') line = LineEdit(parent=window) line.setGeometry(20,200,400,40) style = LineEditStyle() line.setStyle(style) window.show() sys.exit(app.exec())
核心修改点
- 保留
drawPrimitive原生接口签名,直接从widget参数读取悬停状态属性 - 鼠标进入/离开事件中调用
update()触发控件重绘,确保样式实时更新 - 补全
drawPrimitive调用所需的painter、widget参数 - 用
option.rect获取控件实际尺寸,适配不同大小的输入框 - 先调用父类
paintEvent绘制输入框原生的文本、光标内容,再绘制自定义边框,避免文本被边框覆盖
内容的提问来源于stack exchange,提问作者BADAOUI Aymen
相关产品推荐
相关产品推荐

