PyQt按钮右键菜单

本文原创,转载请注明原地址。

作者:酒醉东坡

原文地址:http://blog.csdn.net/jiuzuidongpo/article/details/46507403

实现效果如下图:


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

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

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

样式表的使用:


 
 
  1. self.setStyleSheet( "QMenu{background:purple;}"
  2. "QMenu{border:1px solid lightgray;}"
  3. "QMenu{border-color:green;}"
  4. "QMenu::item{padding:0px 40px 0px 20px;}"
  5. "QMenu::item{height:30px;}"
  6. "QMenu::item{color:blue;}"
  7. "QMenu::item{background:white;}"
  8. "QMenu::item{margin:1px 0px 0px 0px;}"
  9. "QMenu::item:selected:enabled{background:lightgray;}"
  10. "QMenu::item:selected:enabled{color:white;}"
  11. "QMenu::item:selected:!enabled{background:transparent;}"
  12. "QMenu::separator{height:50px;}"
  13. "QMenu::separator{width:1px;}"
  14. "QMenu::separator{background:white;}"
  15. "QMenu::separator{margin:1px 1px 1px 1px;}"
  16. "QMenu#menu{background:white;}"
  17. "QMenu#menu{border:1px solid lightgray;}"
  18. "QMenu#menu::item{padding:0px 40px 0px 30px;}"
  19. "QMenu#menu::item{height:25px;}"
  20. "QMenu#menu::item:selected:enabled{background:lightgray;}"
  21. "QMenu#menu::item:selected:enabled{color:white;}"
  22. "QMenu#menu::item:selected:!enabled{background:transparent;}"
  23. "QMenu#menu::separator{height:1px;}"
  24. "QMenu#menu::separator{background:lightgray;}"
  25. "QMenu#menu::separator{margin:2px 0px 2px 0px;}"
  26. "QMenu#menu::indicator {padding:10px;}"
  27. )

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


 
 
  1. def createContextMenu(self):
  2. '''''
  3. 创建右键菜单
  4. '''
  5. # 必须将ContextMenuPolicy设置为Qt.CustomContextMenu
  6. # 否则无法使用customContextMenuRequested信号
  7. self.setContextMenuPolicy(Qt.CustomContextMenu)
  8. self.customContextMenuRequested.connect(self.showContextMenu)
  9. # 创建QMenu
  10. self.contextMenu = QMenu(self)
  11. self.actionA = self.contextMenu.addAction(QIcon( "images/0.png"), u'| 动作A')
  12. self.actionB = self.contextMenu.addAction(QIcon( "images/0.png"), u'| 动作B')
  13. self.actionC = self.contextMenu.addAction(QIcon( "images/0.png"), u'| 动作C')
  14. #添加二级菜单
  15. self.second = self.contextMenu.addMenu(QIcon( "images/0.png"), u"| 二级菜单")
  16. self.actionD = self.second.addAction(QIcon( "images/0.png"), u'| 动作A')
  17. self.actionE = self.second.addAction(QIcon( "images/0.png"), u'| 动作B')
  18. self.actionF = self.second.addAction(QIcon( "images/0.png"), u'| 动作C')
  19. # 将动作与处理函数相关联
  20. # 这里为了简单,将所有action与同一个处理函数相关联,
  21. # 当然也可以将他们分别与不同函数关联,实现不同的功能
  22. self.actionA.triggered.connect(self.actionHandler)
  23. self.actionB.triggered.connect(self.actionHandler)
  24. self.actionC.triggered.connect(self.actionHandler)
  25. self.actionD.triggered.connect(self.actionHandler)
  26. self.actionE.triggered.connect(self.actionHandler)
  27. self.actionF.triggered.connect(self.actionHandler)

菜单的显示位置:

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


关于按钮的自定义,则包括了一些事件的重新定义和对按钮的ui界面的重新设计和绘制,就不一一列举了。

下面是一个demo包括了按钮的自定义,右键菜单的创建和使用,包括两个文件,图片可以随便找一个,不要过大或者过小就行:

mybutton.py


 
 
  1. # -*- coding: utf-8 -*-
  2. from PyQt4.QtCore import Qt, QRect
  3. from PyQt4.QtGui import QPushButton, QPainter, QPainterPath, QPen, QColor, QPixmap, QIcon, QBrush, QCursor,QMenu
  4. class MenuButton(QPushButton):
  5. def __init__(self,parent = None):
  6. super(MenuButton,self).__init__(parent)
  7. self.setStyleSheet( "QMenu{background:purple;}"
  8. "QMenu{border:1px solid lightgray;}"
  9. "QMenu{border-color:green;}"
  10. "QMenu::item{padding:0px 40px 0px 20px;}"
  11. "QMenu::item{height:30px;}"
  12. "QMenu::item{color:blue;}"
  13. "QMenu::item{background:white;}"
  14. "QMenu::item{margin:1px 0px 0px 0px;}"
  15. "QMenu::item:selected:enabled{background:lightgray;}"
  16. "QMenu::item:selected:enabled{color:white;}"
  17. "QMenu::item:selected:!enabled{background:transparent;}"
  18. "QMenu::separator{height:50px;}"
  19. "QMenu::separator{width:1px;}"
  20. "QMenu::separator{background:white;}"
  21. "QMenu::separator{margin:1px 1px 1px 1px;}"
  22. "QMenu#menu{background:white;}"
  23. "QMenu#menu{border:1px solid lightgray;}"
  24. "QMenu#menu::item{padding:0px 40px 0px 30px;}"
  25. "QMenu#menu::item{height:25px;}"
  26. "QMenu#menu::item:selected:enabled{background:lightgray;}"
  27. "QMenu#menu::item:selected:enabled{color:white;}"
  28. "QMenu#menu::item:selected:!enabled{background:transparent;}"
  29. "QMenu#menu::separator{height:1px;}"
  30. "QMenu#menu::separator{background:lightgray;}"
  31. "QMenu#menu::separator{margin:2px 0px 2px 0px;}"
  32. "QMenu#menu::indicator {padding:10px;}"
  33. )
  34. self.hovered = False
  35. self.pressed = False
  36. self.pressedIcon = QIcon()
  37. self.color = QColor(Qt.gray)
  38. self.opacity = 1.0
  39. self.count = 0
  40. # self.setAutoFillBackground(True)
  41. # self.setStyleSheet("#Check {background-color: rgb(255, 255, 255);}");
  42. self.createContextMenu()
  43. self.count = 0
  44. def createContextMenu(self):
  45. '''''
  46. 创建右键菜单
  47. '''
  48. # 必须将ContextMenuPolicy设置为Qt.CustomContextMenu
  49. # 否则无法使用customContextMenuRequested信号
  50. self.setContextMenuPolicy(Qt.CustomContextMenu)
  51. self.customContextMenuRequested.connect(self.showContextMenu)
  52. # 创建QMenu
  53. self.contextMenu = QMenu(self)
  54. self.actionA = self.contextMenu.addAction(QIcon( "images/0.png"), u'| 动作A')
  55. self.actionB = self.contextMenu.addAction(QIcon( "images/0.png"), u'| 动作B')
  56. self.actionC = self.contextMenu.addAction(QIcon( "images/0.png"), u'| 动作C')
  57. #添加二级菜单
  58. self.second = self.contextMenu.addMenu(QIcon( "images/0.png"), u"| 二级菜单")
  59. self.actionD = self.second.addAction(QIcon( "images/0.png"), u'| 动作A')
  60. self.actionE = self.second.addAction(QIcon( "images/0.png"), u'| 动作B')
  61. self.actionF = self.second.addAction(QIcon( "images/0.png"), u'| 动作C')
  62. # 将动作与处理函数相关联
  63. # 这里为了简单,将所有action与同一个处理函数相关联,
  64. # 当然也可以将他们分别与不同函数关联,实现不同的功能
  65. self.actionA.triggered.connect(self.actionHandler)
  66. self.actionB.triggered.connect(self.actionHandler)
  67. self.actionC.triggered.connect(self.actionHandler)
  68. self.actionD.triggered.connect(self.actionHandler)
  69. self.actionE.triggered.connect(self.actionHandler)
  70. self.actionF.triggered.connect(self.actionHandler)
  71. def showContextMenu(self, pos):
  72. '''''
  73. 右键点击时调用的函数
  74. '''
  75. self.count+= 1
  76. # 菜单显示前,将它移动到鼠标点击的位置
  77. self.contextMenu.exec_(QCursor.pos()) #在鼠标位置显示
  78. #self.contextMenu.show()
  79. print self.count
  80. def actionHandler(self):
  81. '''''
  82. 菜单中的具体action调用的函数
  83. '''
  84. if self.count% 3== 1:
  85. self.setText( u"first")
  86. elif self.count% 3== 2:
  87. self.setText( u"second")
  88. elif self.count% 3== 0:
  89. self.setText( u"third")
  90. def setEnterCursorType(self, Type):
  91. self.cursorType = Type
  92. def setColor(self,color):
  93. self.color = color
  94. def setOpacitys(self,opacity):
  95. self.opacity = opacity
  96. # self.setOpacity(0.5)
  97. def enterEvent(self,event):
  98. self.hovered = True
  99. self.repaint()
  100. QPushButton.enterEvent(self,event)
  101. def leaveEvent(self,event):
  102. self.hovered = False
  103. self.repaint()
  104. self.setCursor(QCursor(Qt.ArrowCursor))
  105. QPushButton.leaveEvent(self,event)
  106. def mousePressEvent(self, event):
  107. self.pressed = True
  108. self.repaint()
  109. QPushButton.mousePressEvent(self,event)
  110. def mouseReleaseEvent(self, event):
  111. self.pressed = False
  112. self.repaint()
  113. QPushButton.mouseReleaseEvent(self,event)
  114. def paintEvent(self,event):
  115. painter = QPainter(self)
  116. btnRect = self.geometry()
  117. iconRect = self.iconSize()
  118. color = QColor(Qt.black)
  119. if self.hovered:
  120. color = self.color
  121. if self.pressed:
  122. color = self.color.darker( 120)
  123. painter.setPen(QPen(QColor(Qt.lightGray), 2))
  124. outline = QPainterPath()
  125. outline.addRoundedRect( 0, 0, btnRect.width(), btnRect.height(), 0, 0)
  126. painter.setOpacity( 1)
  127. painter.drawPath(outline)
  128. painter.setBrush(QBrush(color))
  129. painter.setOpacity(self.opacity)
  130. painter_path = QPainterPath()
  131. painter_path.addRoundedRect( 1, 1, btnRect.width() - 2, btnRect.height() - 2, 0, 0)
  132. if self.hovered:
  133. painter.setClipPath(painter_path)
  134. painter.drawRoundedRect( 1, 1, btnRect.width() - 2, btnRect.height() - 2, 0, 0)
  135. painter.setOpacity( 1)
  136. iconPos,textPos = self.calIconTextPos(btnRect, iconRect)
  137. # 重画文本
  138. if not self.text().isNull():
  139. painter.setFont(self.font())
  140. painter.setPen(QPen(QColor(Qt.black), 2))
  141. painter.drawText(textPos.x(), textPos.y(), textPos.width(), textPos.height(), Qt.AlignCenter, self.text())
  142. # 重画图标
  143. if not self.icon().isNull():
  144. painter.drawPixmap(iconPos, QPixmap(self.icon().pixmap(self.iconSize())))
  145. # 计算图标和文本大小位置
  146. def calIconTextPos(self,btnSize,iconSize):
  147. if self.text().isNull():
  148. iconWidth = iconSize.width()* 3/ 5
  149. iconHeight = iconSize.height()* 3/ 5
  150. else:
  151. iconWidth = iconSize.width()
  152. iconHeight = iconSize.height() - 50
  153. iconX = (btnSize.width()-iconWidth)/ 2
  154. iconY = (btnSize.height()-iconHeight)/ 2
  155. iconPos = QRect()
  156. iconPos.setX(iconX)
  157. iconPos.setY(iconY)
  158. iconPos.setWidth(iconWidth)
  159. iconPos.setHeight(iconHeight)
  160. textPos = QRect()
  161. if not self.text().isNull():
  162. textPos.setX(iconX)
  163. textPos.setY(btnSize.height()- 50)
  164. textPos.setWidth(iconWidth)
  165. textPos.setHeight( 50)
  166. return (iconPos,textPos)

buttontest.py


 
 
  1. # -*- coding: utf-8 -*-
  2. from mybutton import MenuButton
  3. import sys
  4. from PyQt4.QtCore import QTextCodec, QSize, SIGNAL
  5. from PyQt4.QtGui import QDialog, QIcon, QHBoxLayout, QApplication
  6. QTextCodec.setCodecForTr(QTextCodec.codecForName( "utf8"))
  7. class TestDialog(QDialog):
  8. def __init__(self,parent=None):
  9. super(TestDialog,self).__init__(parent)
  10. self.setFixedSize( 200, 200)
  11. self.firMybutton = MenuButton()
  12. self.firMybutton.setFixedSize(QSize( 100, 100))
  13. self.firMybutton.setIcon(QIcon( "windows.png"))
  14. self.firMybutton.setIconSize(QSize( 100, 100))
  15. #self.firMybutton.setText(self.tr("确萨"))
  16. self.connect(self.firMybutton, SIGNAL( "clicked()"),self.cancel)
  17. myLayout = QHBoxLayout()
  18. myLayout.addWidget(self.firMybutton)
  19. self.setLayout(myLayout)
  20. def cancel(self):
  21. self.close()
  22. app=QApplication(sys.argv)
  23. dialog=TestDialog()
  24. dialog.show()
  25. app.exec_()







  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值