python之PyQt按钮右键菜单功能的实现代码


Posted in Python onAugust 17, 2019

实现效果如下图:

python之PyQt按钮右键菜单功能的实现代码

这篇文字主要写了两方面的内容:

第一是按钮的自定义,第二是右键菜单的使用,不仅是按钮的右键菜单,其他一些控件的右键菜单也可以类似创建和使用。

关于右键菜单则是QMenu的一些使用方法有:

样式表的使用:

self.setStyleSheet("QMenu{background:purple;}"
              "QMenu{border:1px solid lightgray;}"
              "QMenu{border-color:green;}"
              "QMenu::item{padding:0px 40px 0px 20px;}"
              "QMenu::item{height:30px;}"  
              "QMenu::item{color:blue;}"
              "QMenu::item{background:white;}"
              "QMenu::item{margin:1px 0px 0px 0px;}"
              "QMenu::item:selected:enabled{background:lightgray;}"
              "QMenu::item:selected:enabled{color:white;}"  
              "QMenu::item:selected:!enabled{background:transparent;}"
              "QMenu::separator{height:50px;}"
              "QMenu::separator{width:1px;}"
              "QMenu::separator{background:white;}"
              "QMenu::separator{margin:1px 1px 1px 1px;}"  
              "QMenu#menu{background:white;}"
              "QMenu#menu{border:1px solid lightgray;}"
              "QMenu#menu::item{padding:0px 40px 0px 30px;}"
              "QMenu#menu::item{height:25px;}"
              "QMenu#menu::item:selected:enabled{background:lightgray;}"
              "QMenu#menu::item:selected:enabled{color:white;}"
              "QMenu#menu::item:selected:!enabled{background:transparent;}"
              "QMenu#menu::separator{height:1px;}"
              "QMenu#menu::separator{background:lightgray;}"
              "QMenu#menu::separator{margin:2px 0px 2px 0px;}"
              "QMenu#menu::indicator {padding:10px;}"
                            )

右键菜单的创建和菜单的信号槽:

def createContextMenu(self): 
    ''''' 
    创建右键菜单 
    ''' 
    # 必须将ContextMenuPolicy设置为Qt.CustomContextMenu 
    # 否则无法使用customContextMenuRequested信号 
    self.setContextMenuPolicy(Qt.CustomContextMenu) 
    self.customContextMenuRequested.connect(self.showContextMenu) 
    # 创建QMenu 
    self.contextMenu = QMenu(self) 
    self.actionA = self.contextMenu.addAction(QIcon("images/0.png"),u'| 动作A') 
    self.actionB = self.contextMenu.addAction(QIcon("images/0.png"),u'| 动作B') 
    self.actionC = self.contextMenu.addAction(QIcon("images/0.png"),u'| 动作C') 
    #添加二级菜单
    self.second = self.contextMenu.addMenu(QIcon("images/0.png"),u"| 二级菜单") 
    self.actionD = self.second.addAction(QIcon("images/0.png"),u'| 动作A')
    self.actionE = self.second.addAction(QIcon("images/0.png"),u'| 动作B')
    self.actionF = self.second.addAction(QIcon("images/0.png"),u'| 动作C')
    # 将动作与处理函数相关联 
    # 这里为了简单,将所有action与同一个处理函数相关联, 
    # 当然也可以将他们分别与不同函数关联,实现不同的功能 
    self.actionA.triggered.connect(self.actionHandler) 
    self.actionB.triggered.connect(self.actionHandler) 
    self.actionC.triggered.connect(self.actionHandler) 
    self.actionD.triggered.connect(self.actionHandler) 
    self.actionE.triggered.connect(self.actionHandler) 
    self.actionF.triggered.connect(self.actionHandler)

菜单的显示位置:

self.contextMenu.exec_(QCursor.pos()) #在鼠标位置显示

关于按钮的自定义,则包括了一些事件的重新定义和对按钮的ui界面的重新设计和绘制,就不一一列举了。
下面是一个demo包括了按钮的自定义,右键菜单的创建和使用,包括两个文件,图片可以随便找一个,不要过大或者过小就行:

mybutton.py
# -*- coding: utf-8 -*- 
from PyQt4.QtCore import Qt, QRect
from PyQt4.QtGui import QPushButton, QPainter, QPainterPath, QPen, QColor, QPixmap, QIcon, QBrush, QCursor,QMenu
class MenuButton(QPushButton):
  def __init__(self,parent = None):
    super(MenuButton,self).__init__(parent)
    self.setStyleSheet("QMenu{background:purple;}"
              "QMenu{border:1px solid lightgray;}"
              "QMenu{border-color:green;}"
              "QMenu::item{padding:0px 40px 0px 20px;}"
              "QMenu::item{height:30px;}"  
              "QMenu::item{color:blue;}"
              "QMenu::item{background:white;}"
              "QMenu::item{margin:1px 0px 0px 0px;}"
              "QMenu::item:selected:enabled{background:lightgray;}"
              "QMenu::item:selected:enabled{color:white;}"  
              "QMenu::item:selected:!enabled{background:transparent;}"
              "QMenu::separator{height:50px;}"
              "QMenu::separator{width:1px;}"
              "QMenu::separator{background:white;}"
              "QMenu::separator{margin:1px 1px 1px 1px;}"  
              "QMenu#menu{background:white;}"
              "QMenu#menu{border:1px solid lightgray;}"
              "QMenu#menu::item{padding:0px 40px 0px 30px;}"
              "QMenu#menu::item{height:25px;}"
              "QMenu#menu::item:selected:enabled{background:lightgray;}"
              "QMenu#menu::item:selected:enabled{color:white;}"
              "QMenu#menu::item:selected:!enabled{background:transparent;}"
              "QMenu#menu::separator{height:1px;}"
              "QMenu#menu::separator{background:lightgray;}"
              "QMenu#menu::separator{margin:2px 0px 2px 0px;}"
              "QMenu#menu::indicator {padding:10px;}"
                            )
    self.hovered = False
    self.pressed = False
    self.pressedIcon = QIcon()
    self.color = QColor(Qt.gray)
    self.opacity = 1.0
    self.count = 0
#     self.setAutoFillBackground(True)
#     self.setStyleSheet("#Check {background-color: rgb(255, 255, 255);}");
    self.createContextMenu() 
    self.count = 0
  def createContextMenu(self): 
    ''''' 
              创建右键菜单 
    ''' 
    # 必须将ContextMenuPolicy设置为Qt.CustomContextMenu 
    # 否则无法使用customContextMenuRequested信号 
    self.setContextMenuPolicy(Qt.CustomContextMenu) 
    self.customContextMenuRequested.connect(self.showContextMenu) 
    # 创建QMenu 
    self.contextMenu = QMenu(self) 
    self.actionA = self.contextMenu.addAction(QIcon("images/0.png"),u'| 动作A') 
    self.actionB = self.contextMenu.addAction(QIcon("images/0.png"),u'| 动作B') 
    self.actionC = self.contextMenu.addAction(QIcon("images/0.png"),u'| 动作C') 
    #添加二级菜单
    self.second = self.contextMenu.addMenu(QIcon("images/0.png"),u"| 二级菜单") 
    self.actionD = self.second.addAction(QIcon("images/0.png"),u'| 动作A')
    self.actionE = self.second.addAction(QIcon("images/0.png"),u'| 动作B')
    self.actionF = self.second.addAction(QIcon("images/0.png"),u'| 动作C')
    # 将动作与处理函数相关联 
    # 这里为了简单,将所有action与同一个处理函数相关联, 
    # 当然也可以将他们分别与不同函数关联,实现不同的功能 
    self.actionA.triggered.connect(self.actionHandler) 
    self.actionB.triggered.connect(self.actionHandler) 
    self.actionC.triggered.connect(self.actionHandler) 
    self.actionD.triggered.connect(self.actionHandler) 
    self.actionE.triggered.connect(self.actionHandler) 
    self.actionF.triggered.connect(self.actionHandler)  
  def showContextMenu(self, pos): 
    ''''' 
    右键点击时调用的函数 
    ''' 
    self.count+=1
    # 菜单显示前,将它移动到鼠标点击的位置 
    self.contextMenu.exec_(QCursor.pos()) #在鼠标位置显示
    #self.contextMenu.show() 
    print self.count
  def actionHandler(self): 
    ''''' 
    菜单中的具体action调用的函数 
    ''' 
    if self.count%3==1:
      self.setText(u"first")
    elif self.count%3==2:
      self.setText(u"second")
    elif self.count%3==0:
      self.setText(u"third")
  def setEnterCursorType(self, Type):
    self.cursorType = Type
  def setColor(self,color):
    self.color = color
  def setOpacitys(self,opacity):
    self.opacity = opacity
#     self.setOpacity(0.5)
  def enterEvent(self,event):
    self.hovered = True
    self.repaint()
    QPushButton.enterEvent(self,event)
  def leaveEvent(self,event):
    self.hovered = False
    self.repaint()
    self.setCursor(QCursor(Qt.ArrowCursor)) 
    QPushButton.leaveEvent(self,event)
  def mousePressEvent(self, event):
    self.pressed = True
    self.repaint()
    QPushButton.mousePressEvent(self,event)
  def mouseReleaseEvent(self, event):
    self.pressed = False
    self.repaint()
    QPushButton.mouseReleaseEvent(self,event)
  def paintEvent(self,event):
    painter = QPainter(self)
    btnRect = self.geometry()
    iconRect = self.iconSize()
    color = QColor(Qt.black)
    if self.hovered:
      color = self.color
    if self.pressed:
      color = self.color.darker(120)
    painter.setPen(QPen(QColor(Qt.lightGray),2))
    outline = QPainterPath()
    outline.addRoundedRect(0, 0, btnRect.width(), btnRect.height(), 0, 0)
    painter.setOpacity(1)
    painter.drawPath(outline)
    painter.setBrush(QBrush(color)) 
    painter.setOpacity(self.opacity)
    painter_path = QPainterPath()
    painter_path.addRoundedRect(1, 1, btnRect.width() - 2, btnRect.height() - 2, 0, 0)
    if self.hovered:
      painter.setClipPath(painter_path)
      painter.drawRoundedRect(1, 1, btnRect.width() - 2, btnRect.height() - 2, 0, 0)
    painter.setOpacity(1)    
    iconPos,textPos = self.calIconTextPos(btnRect, iconRect)
    # 重画文本
    if not self.text().isNull():
      painter.setFont(self.font())
      painter.setPen(QPen(QColor(Qt.black),2))
      painter.drawText(textPos.x(), textPos.y(), textPos.width(), textPos.height(), Qt.AlignCenter, self.text())
      # 重画图标
    if not self.icon().isNull():
      painter.drawPixmap(iconPos, QPixmap(self.icon().pixmap(self.iconSize())))
  # 计算图标和文本大小位置
  def calIconTextPos(self,btnSize,iconSize):
    if self.text().isNull():
      iconWidth = iconSize.width()*3/5
      iconHeight = iconSize.height()*3/5
    else:
      iconWidth = iconSize.width()
      iconHeight = iconSize.height() - 50
    iconX = (btnSize.width()-iconWidth)/2
    iconY = (btnSize.height()-iconHeight)/2
    iconPos = QRect()
    iconPos.setX(iconX)
    iconPos.setY(iconY)
    iconPos.setWidth(iconWidth)
    iconPos.setHeight(iconHeight)
    textPos = QRect()
    if not self.text().isNull():
      textPos.setX(iconX)
      textPos.setY(btnSize.height()- 50)
      textPos.setWidth(iconWidth)
      textPos.setHeight(50)
    return (iconPos,textPos)
1
buttontest.py
# -*- coding: utf-8 -*- 
from mybutton import MenuButton
import sys
from PyQt4.QtCore import QTextCodec, QSize, SIGNAL
from PyQt4.QtGui import QDialog, QIcon, QHBoxLayout, QApplication
QTextCodec.setCodecForTr(QTextCodec.codecForName("utf8"))
class TestDialog(QDialog):
  def __init__(self,parent=None):
    super(TestDialog,self).__init__(parent)
    self.setFixedSize(200,200)
    self.firMybutton = MenuButton()
    self.firMybutton.setFixedSize(QSize(100,100))
    self.firMybutton.setIcon(QIcon("windows.png"))
    self.firMybutton.setIconSize(QSize(100,100))
    #self.firMybutton.setText(self.tr("确萨"))
    self.connect(self.firMybutton, SIGNAL("clicked()"),self.cancel)
    myLayout = QHBoxLayout()
    myLayout.addWidget(self.firMybutton)
    self.setLayout(myLayout)
  def cancel(self):
    self.close()
app=QApplication(sys.argv)
dialog=TestDialog()
dialog.show()
app.exec_()

总结

以上所述是小编给大家介绍的python之PyQt按钮右键菜单功能的实现代码,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Python 相关文章推荐
python正则表达式re模块详细介绍
May 29 Python
Python实现PS图像抽象画风效果的方法
Jan 23 Python
python对excel文档去重及求和的实例
Apr 18 Python
Scrapy框架使用的基本知识
Oct 21 Python
解决PyCharm控制台输出乱码的问题
Jan 16 Python
Python字典的核心底层原理讲解
Jan 24 Python
Pytorch实现GoogLeNet的方法
Aug 18 Python
基于Python实现扑克牌面试题
Dec 11 Python
kafka监控获取指定topic的消息总量示例
Dec 23 Python
python判断变量是否为int、字符串、列表、元组、字典的方法详解
Feb 13 Python
使用jupyter notebook将文件保存为Markdown,HTML等文件格式
Apr 14 Python
对PyTorch中inplace字段的全面理解
May 22 Python
pytorch 在网络中添加可训练参数,修改预训练权重文件的方法
Aug 17 #Python
python PyQt5/Pyside2 按钮右击菜单实例代码
Aug 17 #Python
Pytorch 实现自定义参数层的例子
Aug 17 #Python
Python中PyQt5/PySide2的按钮控件使用实例
Aug 17 #Python
画pytorch模型图,以及参数计算的方法
Aug 17 #Python
pytorch 共享参数的示例
Aug 17 #Python
Pytorch卷积层手动初始化权值的实例
Aug 17 #Python
You might like
用Flash图形化数据(二)
2006/10/09 PHP
Window下PHP三种运行方式图文详解
2013/06/11 PHP
解析zend studio中直接导入svn中的项目的方法步骤
2013/06/21 PHP
destoon二次开发入门示例
2014/06/20 PHP
PHP函数in_array()使用详解
2014/08/20 PHP
修改WordPress中文章编辑器的样式的方法详解
2015/12/15 PHP
解决laravel中日志权限莫名变成了root的问题
2019/10/17 PHP
一段利用WSH获取登录时间的jscript代码
2008/05/11 Javascript
很可爱的输入框
2008/08/03 Javascript
js querySelector和getElementById通过id获取元素的区别
2012/04/20 Javascript
javascript新建标签,判断键盘输入,以及判断焦点(示例代码)
2013/11/25 Javascript
jQuery中append()方法用法实例
2014/12/25 Javascript
js获取form的方法
2015/05/06 Javascript
bootstrap是什么_动力节点Java学院整理
2017/07/14 Javascript
Vue 项目代理设置的优化
2018/04/17 Javascript
vue操作下拉选择器获取选择的数据的id方法
2018/08/24 Javascript
vue elementUI tree树形控件获取父节点ID的实例
2018/09/12 Javascript
jQuery实现侧边栏隐藏与显示的方法详解
2018/12/22 jQuery
微信小程序实现单列下拉菜单效果
2019/04/25 Javascript
[06:09]辉夜杯主赛事开幕式
2015/12/25 DOTA
python用ConfigObj读写配置文件的实现代码
2013/03/04 Python
Python变量和数据类型详解
2017/02/15 Python
Python网络编程详解
2017/10/31 Python
python opencv3实现人脸识别(windows)
2018/05/25 Python
PyTorch预训练的实现
2019/09/18 Python
Python函数式编程实例详解
2020/01/17 Python
PyCharm 2020.1版安装破解注册码永久激活(激活到2089年)
2020/09/24 Python
linux面试题参考答案(10)
2016/10/26 面试题
医药代表个人求职信范本
2013/12/19 职场文书
六查六看自查材料
2014/02/17 职场文书
学生操行评语大全
2014/04/24 职场文书
大学生实习证明范本
2014/09/19 职场文书
2015元旦家电促销活动策划方案
2014/12/09 职场文书
同事去世追悼词
2015/06/23 职场文书
go语言中切片与内存复制 memcpy 的实现操作
2021/04/27 Golang
Python加密与解密模块hashlib与hmac
2022/06/05 Python