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按钮右键菜单功能的实现代码,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

(0)

相关推荐

  • python3+PyQt5重新实现QT事件处理程序

    本文是对<Python Qt GUI快速编程>的第10章的例子events用Python3+PyQt5进行改写,涉及到重新实现QWidget的事件处理程序.本例子涉及到上下文菜单,鼠标事件,键盘事件,可作为重新实现事件处理程序的参考. 注:在创建上下文菜单最简单的方式使用Qwidget.addAction()把动作添加到窗口部件中,再把窗口部件的上下文菜单策略设置为Qt.ActionsContextMenu即可,但是如果像本例子一样要根据不同的状态来提供不同的选项,则要重新实现上下文菜单事件处

  • Python3 安装PyQt5及exe打包图文教程

    环境: Python 3.6.4 + Pycharm Professional 2017.3.3 + PyQt5 + PyQt5-tools ① Python 3 安装 Python 3.x 安装时,默认勾选ADD Python 3.6 to PATH和ADD Python to environment variables的情况下,系统会向path中增加以下两个环境变量. D:\Program Files\Python36\Scripts\; D:\Program Files\Python36\

  • python3+PyQt5图形项的自定义和交互 python3实现page Designer应用程序

    本文通过Python3+PyQt5实现<python Qt Gui 快速编程>这本书的page Designer应用程序,采用QGraphicsView,QGraphicsScene,QGraphicsItem,这个程序包含有多个文本,图片和框的页面.有些图形类在PyQt5已过时,所以本代码改动幅度比较大.主要的类或方法的改变如下: QMatrix==>QTransform setMatrix==>setTransform rotate ==> setRotation 本例中

  • python+pyqt实现右下角弹出框

    本文实例为大家分享了pyqt实现右下角弹出框的具体代码,供大家参考,具体内容如下 构造函数中: self.desktop=QDesktopWidget() self.move((self.desktop.availableGeometry().width()-self.width()),self.desktop.availableGeometry().height()) #初始化位置到右下角 self.showAnimation() #弹出动画 def showAnimation(self):

  • python3+PyQt5+Qt Designer实现堆叠窗口部件

    本文是对<Python Qt GUI快速编程>的第9章的堆叠窗口例子Vehicle Rental用Python3+PyQt5+Qt Designer进行改写. 第一部分无借用Qt Designer,完全用代码实现. 第二部分则借用Qt Designer,快速实现. 第一部分: import sys from PyQt5.QtCore import (Qt) from PyQt5.QtWidgets import (QApplication, QComboBox, QDialog, QDialo

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

    实现效果如下图: 这篇文字主要写了两方面的内容: 第一是按钮的自定义,第二是右键菜单的使用,不仅是按钮的右键菜单,其他一些控件的右键菜单也可以类似创建和使用. 关于右键菜单则是QMenu的一些使用方法有: 样式表的使用: self.setStyleSheet("QMenu{background:purple;}" "QMenu{border:1px solid lightgray;}" "QMenu{border-color:green;}" &

  • Python编写可视化界面的全过程(Python+PyCharm+PyQt)

    最近开始学习Python,但只限于看理论,编几行代码,觉得没有意思,就想能不能用Python编写可视化的界面.遂查找了相关资料,发现了PyQt,由于前一段时间刚看过Qt,而且对Qt的印象很好,于是觉得用PyQt应该是一个比较愉快的选择. 1.前言 PyQt的版本需要与Python的版本保持一致,在这里我用的PyQT的版本是 PyQt5-5.6-gpl-Py3.5-Qt5.6.0-x64.exe,具体下载方式,请直接搜索.由于该版本需要v3.5版本的Python,所以首先需要安装Python3.5

  • Python 窗体(tkinter)按钮 位置实例

    如下所示: import tkinter def go(): #函数 print("go函数") win=tkinter.Tk() #构造窗体 win.title("hello zhaolin")#标题 win.geometry("800x800+300+0")#800宽度,800高度,x,y坐标,左上角 button=tkinter.Button(win,text="有种点我",command=go) #收到消息执行go函数

  • python PyQt5/Pyside2 按钮右击菜单实例代码

    具体代码如下所述: import sys from PySide2.QtGui import * from PySide2.QtCore import * from PySide2.QtWidgets import * class MainForm(QMainWindow): def __init__(self, parent=None): super(MainForm, self).__init__(parent) # create button self.button = QPushButt

  • python tkinter 获得按钮的文本值

    背景 最近本菜鸡在学习 python GUI,从 tkinter 入门,想先做个小软件练习一下 思来想去,决定做一个 计算器 计算器代码在这里,传送门 问题重现 但直接使用循环创建数字按钮时遇到了问题,问题代码如下 for i in range(3): num_frame = tk.Frame(major_frame) num_frame.pack() for count in range(3*i+1, 3*i+4): button = tk.Button( num_frame, text =

  • Python+tkinter模拟“记住我”自动登录实例代码

    本文分享的代码主要是通过Python+tkinter模拟"记住我"自动登录的功能,具体介绍如下. 基本思路:如果某次登录成功,则创建临时文件记录有关信息,每次启动程序时尝试自动获取上次登录成功的信息并自动编写.本文主要演示思路,可根据实际系统中的需要进行改写,例如读取数据库并验证用户名和密码是否正确.对用户名和密码进行本地加密存储等等. import tkinter import tkinter.messagebox import os import os.path # 获取Windo

  • python selenium实现发送带附件的邮件代码实例

    这篇文章主要介绍了python selenium实现发送带附件的邮件代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 163邮件登录首页 登录成功断言是否有退出按钮 点击退出退出登录 代码如下 from selenium import webdriver import unittest import time class VisitSogouByChrome(unittest.TestCase): def setUp(self): # 启

  • python实现无边框进度条的实例代码

    上python课程时需要设计一个系统,想着为系统加一个启动动画,所以做成了图片加进度条的形式. 本文旨在用python实现无边框的进度条,并在其基础上加了图片,体现了某程序加载动画的效果 实现说明 1.进度条的部分用到了tkinter中的画布组件 2.图片无边框显示用到了PYQT5中的QMainWindow, QApplication (由于水平有限,只好用两个不同的库来实现) 源代码 import sys from PyQt5.QtCore import Qt from PyQt5.QtWid

  • Python实现淘宝秒杀功能的示例代码

    1.安装 Selenium 模块 Selenium支持很多浏览器,我选择的是Firefox浏览器. 安装方法: ①打开cmd: ②输入命令 pip install selenium: ③回车,等待自动安装: ④当最后一行代码出现Successfully install selenium-XX时,表示安装成功. 2. 插件 FireBug FireBug 是火狐浏览器的一款查看代码元素的插件,可以快速的定位元素,selenium的重点就是元素定位,只有定到位了,才能进行下一步操作. 测试安装成功,

  • Python聊天室带界面实现的示例代码(tkinter,Mysql,Treading,socket)

    一.前言 我用的是面向对象写的,把界面功能模块封装成类,然后在客户端创建对象然后进行调用.好处就是方便我们维护代码以及把相应的信息封装起来,每一个实例都是各不相同的. 所有的界面按钮处理事件都在客户端,在创建界面对象是会把客户端的处理事件函数作为创建对象的参数,之后再按钮上绑定这个函数,当点击按钮时便会回调函数 二.登录界面实现 登录界面模块chat_login_panel.py from tkinter import * # 导入模块,用户创建GUI界面 # 登陆界面类 class Login

随机推荐