forked from PyQt5/PyQt
-
Notifications
You must be signed in to change notification settings - Fork 6
/
QQMenu.py
134 lines (113 loc) · 3.59 KB
/
QQMenu.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on 2021/4/7
@author: Irony
@site: https://pyqt.site , https://github.com/PyQt5
@email: [email protected]
@file: QQMenu
@description:
"""
import string
from random import choice, randint
try:
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QPainter, QFont, QIcon
from PyQt5.QtWidgets import QLabel, QMenu, QApplication
except ImportError:
from PySide2.QtCore import Qt
from PySide2.QtGui import QPixmap, QPainter, QFont, QIcon
from PySide2.QtWidgets import QLabel, QMenu, QApplication
Style = """
QMenu {
/* 半透明效果 */
background-color: rgba(255, 255, 255, 230);
border: none;
border-radius: 4px;
}
QMenu::item {
border-radius: 4px;
/* 这个距离很麻烦需要根据菜单的长度和图标等因素微调 */
padding: 8px 48px 8px 36px; /* 36px是文字距离左侧距离*/
background-color: transparent;
}
/* 鼠标悬停和按下效果 */
QMenu::item:selected {
border-radius: 0px;
/* 半透明效果 */
background-color: rgba(232, 232, 232, 232);
}
/* 禁用效果 */
QMenu::item:disabled {
background-color: transparent;
}
/* 图标距离左侧距离 */
QMenu::icon {
left: 15px;
}
/* 分割线效果 */
QMenu::separator {
height: 1px;
background-color: rgb(232, 236, 243);
}
"""
def get_icon():
# 测试模拟图标
pixmap = QPixmap(16, 16)
pixmap.fill(Qt.transparent)
painter = QPainter()
painter.begin(pixmap)
painter.setFont(QFont('Webdings', 11))
painter.setPen(Qt.GlobalColor(randint(4, 18)))
painter.drawText(0, 0, 16, 16, Qt.AlignCenter,
choice(string.ascii_letters))
painter.end()
return QIcon(pixmap)
def about_qt():
# 关于Qt
QApplication.instance().aboutQt()
class Window(QLabel):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(*args, **kwargs)
self.resize(400, 400)
self.setAlignment(Qt.AlignCenter)
self.setText('右键弹出菜单')
self.context_menu = QMenu(self)
self.init_menu()
def contextMenuEvent(self, event):
self.context_menu.exec_(event.globalPos())
def init_menu(self):
# 背景透明
self.context_menu.setAttribute(Qt.WA_TranslucentBackground)
# 无边框、去掉自带阴影
self.context_menu.setWindowFlags(
self.context_menu.windowFlags() | Qt.FramelessWindowHint | Qt.NoDropShadowWindowHint)
# 模拟菜单项
for i in range(10):
if i % 2 == 0:
action = self.context_menu.addAction('菜单 %d' % i, about_qt)
action.setEnabled(i % 4)
elif i % 3 == 0:
self.context_menu.addAction(get_icon(), '菜单 %d' % i, about_qt)
if i % 4 == 0:
self.context_menu.addSeparator()
if i % 5 == 0:
# 二级菜单
# 二级菜单
menu = QMenu('二级菜单 %d' % i, self.context_menu)
# 背景透明
menu.setAttribute(Qt.WA_TranslucentBackground)
# 无边框、去掉自带阴影
menu.setWindowFlags(menu.windowFlags() | Qt.FramelessWindowHint | Qt.NoDropShadowWindowHint)
for j in range(3):
menu.addAction(get_icon(), '子菜单 %d' % j)
self.context_menu.addMenu(menu)
if __name__ == '__main__':
import sys
import cgitb
cgitb.enable(format='text')
app = QApplication(sys.argv)
app.setStyleSheet(Style)
w = Window()
w.show()
sys.exit(app.exec_())