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开发简易版在线音乐播放器
Mar 03 Python
python中使用xlrd读excel使用xlwt写excel的实例代码
Jan 31 Python
python 调用钉钉机器人的方法
Feb 20 Python
python生成器用法实例详解
Nov 22 Python
python 利用turtle模块画出没有角的方格
Nov 23 Python
python3 tkinter实现添加图片和文本
Nov 26 Python
使用keras和tensorflow保存为可部署的pb格式
May 25 Python
Python importlib模块重载使用方法详解
Oct 13 Python
Django-celery-beat动态添加周期性任务实现过程解析
Nov 26 Python
Pycharm 如何一键加引号的方法步骤
Feb 05 Python
Python基础之函数嵌套知识总结
May 23 Python
python机器学习Github已达8.9Kstars模型解释器LIME
Nov 23 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
PHP网页游戏学习之Xnova(ogame)源码解读(三)
2014/06/23 PHP
PHP动态编译出现Cannot find autoconf的解决方法
2014/11/05 PHP
深入理解PHP中的empty和isset函数
2016/05/26 PHP
Laravel框架模板加载,分配变量及简单路由功能示例
2018/06/11 PHP
jQuery操作input值的各种方法总结
2013/11/21 Javascript
javascript实现简单的二级联动
2015/03/19 Javascript
可以浮动某个物体的jquery控件用法实例
2015/07/24 Javascript
Jquery Mobile 自定义按钮图标
2015/11/18 Javascript
javascript iframe跨域详解
2016/10/26 Javascript
jQuery中table数据的值拷贝和拆分
2017/03/19 Javascript
Angular中点击li标签实现更改颜色的核心代码
2017/12/08 Javascript
vue基础之使用get、post、jsonp实现交互功能示例
2019/03/12 Javascript
详解vue 不同环境配置不同的打包命令
2019/04/07 Javascript
js实现一款简单踩白块小游戏(曾经很火)
2019/12/02 Javascript
Vue组件间的通信pubsub-js实现步骤解析
2020/03/11 Javascript
vue 路由懒加载中给 Webpack Chunks 命名的方法
2020/04/24 Javascript
vue mvvm数据响应实现
2020/11/11 Javascript
python脚本实现数据导出excel格式的简单方法(推荐)
2016/12/30 Python
python常见排序算法基础教程
2017/04/13 Python
Python数据可视化实现正态分布(高斯分布)
2019/08/21 Python
Python使用matplotlib实现交换式图形显示功能示例
2019/09/06 Python
Python爬虫爬取、解析数据操作示例
2020/03/27 Python
PyCharm 光标变成黑块的解决方式
2021/02/06 Python
html5指南-3.如何实现html元素拖拽功能
2013/01/07 HTML / CSS
详解使用HTML5 Canvas创建动态粒子网格动画
2016/12/14 HTML / CSS
Grow Gorgeous美国官网:只要八天,体验唤醒毛囊后新生的茂密秀发
2018/06/04 全球购物
瑞士灯具购物网站:Lampenwelt.ch
2018/07/08 全球购物
韩语专业本科生求职信
2013/10/01 职场文书
电子商务毕业生求职信
2013/11/10 职场文书
大学本科毕业生的自我鉴定
2013/11/26 职场文书
不服从上级领导安排的检讨书
2014/09/14 职场文书
司机岗位职责
2015/02/04 职场文书
教师专业技术工作总结2015
2015/05/13 职场文书
团队拓展训练心得体会
2016/01/12 职场文书
浅谈pytorch中stack和cat的及to_tensor的坑
2021/05/20 Python
maven 解包依赖项中的文件的解决方法
2022/07/15 Java/Android