PyQt5实现平滑移动侧边菜单栏效果的示例
CDrawer.py
#!/usr/bin/env python # encoding: utf-8 ''' @author: JHC @license: None @contact: JHC000abc@gmail.com @file: CDrawer.py @time: 2022/07/19/ 16:56 @desc: ''' from PyQt5.QtCore import Qt, QPropertyAnimation, QEasingCurve, QPoint, QPointF from PyQt5.QtGui import QMouseEvent from PyQt5.QtWidgets import QWidget, QApplication class CDrawer(QWidget): LEFT, TOP, RIGHT, BOTTOM = range(4) def __init__(self, *args, stretch=1 / 3, direction=0, widget=None, **kwargs): super(CDrawer, self).__init__(*args, **kwargs) self.setWindowFlags(self.windowFlags( ) | Qt.FramelessWindowHint | Qt.Popup | Qt.NoDropShadowWindowHint) self.setAttribute(Qt.WA_StyledBackground, True) self.setAttribute(Qt.WA_TranslucentBackground, True) # 进入动画 self.animIn = QPropertyAnimation( self, duration=500, easingCurve=QEasingCurve.OutCubic) self.animIn.setPropertyName(b'pos') # 离开动画 self.animOut = QPropertyAnimation( self, duration=500, finished=self.onAnimOutEnd, easingCurve=QEasingCurve.OutCubic) self.animOut.setPropertyName(b'pos') self.animOut.setDuration(500) self.setStretch(stretch) # 占比 self.direction = direction # 方向 # 半透明背景 self.alphaWidget = QWidget( self, objectName='CDrawer_alphaWidget', styleSheet='#CDrawer_alphaWidget{background:rgba(55,55,55,100);}') self.alphaWidget.setAttribute(Qt.WA_TransparentForMouseEvents, True) self.setWidget(widget) # 子控件 def resizeEvent(self, event): self.alphaWidget.resize(self.size()) super(CDrawer, self).resizeEvent(event) def mousePressEvent(self, event): pos = event.pos() if pos.x() >= 0 and pos.y() >= 0 and self.childAt(pos) == None and self.widget: if not self.widget.geometry().contains(pos): self.animationOut() return super(CDrawer, self).mousePressEvent(event) def show(self): super(CDrawer, self).show() parent = self.parent().window() if self.parent() else self.window() if not parent or not self.widget: return # javascript设置Drawer大小和主窗口一致 self.setGeometry(parent.geometry()) geometry = self.geometry() self.animationIn(geometry) def animationIn(self, geometry): """进入动画 :param geometry: """ if self.direction == self.LEFT: # 左侧抽屉 self.widget.setGeometry( 0, 0, int(geometry.width() * self.stretch), geometry.height()) self.widget.hide() self.animIn.setStartValue(QPoint(-self.widget.width(), 0)) self.animIn.setEndValue(QPoint(0, 0)) self.animIn.start() self.widget.show() elif self.direction == self.TOP: # 上方抽屉 self.widget.setGeometry( 0, 0, geometry.width(), int(geometry.height() * self.stretch)) self.widget.hide() self.animIn.setStartValue(QPoint(0, -self.widget.height())) self.animIn.setEndValue(QPoint(0, 0)) self.animIn.start() self.widget.show() elif self.direction == self.RIGHT: # 右侧抽屉 width = int(geometry.width() * self.stretch) self.widget.setGeometry( geometry.width() - width, 0, width, geometry.height()) selfandroid.widget.hide() self.animIn.setStartValue(QPoint(self.width(), 0)) self.animIn.setEndValue( QPoint(self.width() - self.widget.width(), 0)) self.animIn.start() self.widget.show() elif self.direction == self.BOTTOM: # 下方抽屉 height = int(geometry.height() * self.stretch) self.widget.setGeometry( 0, geometry.height() - height, geometry.width(), height) self.widget.hide() self.animIn.setStartValue(QPoint(0, self.height())) self.animIn.setEndValue( QPoint(0, self.height() - self.widget.height())) self.animIn.start() self.widget.show() def animationOut(self): """离开动画 """ self.animIn.stop() # 停止进入动画 geometry = self.widget.geometry() if self.direction == self.LEFT: # 左侧抽屉 self.animOut.setStartValue(geometry.topLeft()) self.animOut.setEndValue(QPoint(-self.widget.width(), 0)) self.animOut.start() elif self.direction == self.TOP: # 上方抽屉 self.animOut.setStartValue(QPoint(0, geometry.y())) self.animOut.setEndValue(QPoint(0, -self.widget.height())) self.animOut.start() elif self.direction == self.RIGHT: # 右侧抽屉 self.animOut.setStartValue(QPoint(geometry.x(), 0)) self.animOut.setEndValue(QPoint(self.width(), 0)) self.animOut.start() elif self.direction == self.BOTTOM: # 下方抽屉 self.animOut.setStartValue(QPoint(0, geometry.y())) self.animOut.setEndValue(QPoint(0, self.height())) self.animOut.start() def onAnimOutEnd(self): """离开动画结束 """ # 模拟点击外侧关闭 QApplication.sendEvent(self, QMouseEvent( QMouseEvent.MouseButtonPress, QPointF(-1, -1), Qt.LeftButton, Qt.NoButton, Qt.NoModifier)) def setWidget(self, widget): """设置子控件 :param widget: """ self.widget = widget if widget: widget.setParent(self) self.animIn.setTargetObject(widget) self.animOut.setTargetObject(widget) def setEasingCurve(self, easingCurve): """设置动画曲线 :param easingCurve: """ self.animIn.setEasingCurve(easingCurve) def getStretch(self): """获取占比 """ return self.stretch javascript def setStretch(self, stretch): """设置占比 :param stretch: """ self.stretch = max(0.1, min(stretch, 0.9)) def getDirection(self): """获取方向 """ return self.direction def setDirection(self, direction): """设置方向 :param direction: """ direction = int(direction) if direction < 0 or direction > 3: direction = self.LEFT self.direction = direction
Qt.py
#!/usr/bin/env python # encoding: utf-8 ''' @author: JHC @license: None @contact: JHC000abc@gmail.com @file: QT.py @time: 2022/07/19/ 16:53 @desc: ''' from PyQt5.QtCore import Qt from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * from CDrawer import CDrawer import sys import cgitb sys.excepthook = cgitb.enable(1, None, 5, '') from PyQt5.QtWidgets import QApplication class DrawerWidget(QWidget): def __init__(self, *args, **kwargs): super(DrawerWidget, self).__init__(*args, **kwargs) self.setAttribute(Qt.WAjavascript_StyledBackground, True) self.setStyleSheet('DrawerWidget{background:white;}') self.lineedit = QLineEdit(self) layout = QvboxLayout(self) layout.addwidget(self.lineedit) layout.addWidget(QPushButton('button', self,clicked=self._click)) layout.addWidget(QPushButton('button2', self, clicked=self._click2)) def _click(self): if self.lineedit.text() != "": print("框中输入的文字为:{}".format(self.lineedit.text())) self.lineedit.clear() else: print("框中未输入的文字为") def _click2(self): print("没用") class Window(QWidget): def __init__(self, *args, **kwargs): super(Window, self).__init__(*args, **kwargs) self.resize(480, 960) self.entermouse = 0 self.flag = 0 self.x = 0 self.y = 0 # layout = QGridLayout(self) # layout.addWidget(QPushButton('侧边栏', self, clicked=self.doOpenLeft), 1, 0) def mouseMoveEvent(self, event): print("-----------------------mouseMoveEvent-----------------------") if self.entermouse == 1: www.devze.com self.x = event.x() self.y = event.y() self.flag = 1 if self.x < 100 : self.doOpenLeft() self.update() def mousePressEvent(self, event): if self.entermouse == 1 and self.flag == 1 and event.button() == Qt.LeftButton: self.x = event.x() self.y = event.y() print("按压 ",self.x,self.y) else: pass self.update() def mouseReleaseEvent(self, event): if self.entermouse == 1 and self.flag == 1 and event.button() == Qt.LeftButton: self.x = event.x() self.y = event.y() print("松开 ", self.x, self.y) else: pass self.update() def enterEvent(self, *args, **kwargs): if self.entermouse == 0: self.entermouse = 1 else: pass def leaveEvent(self, *args, **kwargs): if self.entermouse == 1: self.entermouse = 0 else: pass def doOpenLeft(self): if not hasattr(self, 'leftDrawer'): self.leftDrawer = CDrawer(self, direction=CDrawer.LEFT) self.leftDrawer.setWidget(DrawerWidget(self.leftDrawer)) self.leftDrawer.show() def paintEvent(self, event): super().paintEvent(event) self.painter = QPainter() self.painter.begin(self) self.update() if self.x != 0 and self.y != 0 and self.entermouse == 1: # print("self.x,self.y ",self.x,self.y) self.update() else: self.update() self.update() self.painter.end() if __name__ == '__main__': app = QApplication(sys.argv) w = Window() w.show() sys.exit(app.exec_())
到此这篇关于PyQt5实现平滑移动侧边菜单栏效果的示例的文章就介绍到这了,更多相关PyQt5 平滑移动侧边菜单栏内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!
精彩评论