当前位置: 代码网 > it编程>编程语言>C/C++ > PyQt5实现平滑移动侧边菜单栏效果的示例

PyQt5实现平滑移动侧边菜单栏效果的示例

2025年05月14日 C/C++ 我要评论
cdrawer.py#!/usr/bin/env python# encoding: utf-8'''@author: jhc @license: none@contact: jhc000abc@gm

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
        # 设置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())
            self.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

    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.wa_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:
            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 平滑移动侧边菜单栏内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网! 

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com