Помогите переопределить QMenu
Помогите переопределить QMenu.
main.py :
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import Qt, QRect
from KMenu import KMenu
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.mwidget = QMainWindow(self)
self.setWindowFlags(Qt.Tool | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
self.setGeometry(QRect(100, 100, 100, 100))
self.menu = KMenu(self.mwidget)
self.menu.setStyleSheet("QMenu {"
"background-color: #ABABAB; /* sets background of the menu */"
"border: 1px solid black;"
"}"
)
action = self.menu.addAction('&Exit')
action.triggered.connect(lambda: quit())
self.show()
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
ex = MainWindow()
sys.exit(app.exec_())
KMenu.py:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from PyQt5 import QtCore
import PyQt5.QtWidgets as qtw
from PyQt5.QtWidgets import QAction, QMenu
class KMenu(qtw.QMenu):
def __init__(self, root):
super().__init__(root)
self.parent = root
print('KMenu')
def setStyleSheet(self, *args, **kwargs):
self.parent.setStyleSheet(*args, **kwargs)
def addAction(self, *args, **kwargs):
self.parent.addAction(*args, **kwargs)
При запуске main.py получаю ошибку:
Traceback (most recent call last): File "C:\Users\User\Desktop\main.py", line 32, in <module> ex = MainWindow() File "C:\Users\User\Desktop\main.py", line 24, in __init__ action = self.menu.addAction('&Exit') File "C:\Users\User\Desktop\KMenu.py", line 18, in addAction self.parent.addAction(*args, **kwargs) TypeError: addAction(self, QAction): argument 1 has unexpected type 'str'
Нужно получить немного видоизмененный класс PyQt5.QtWidgets.QMenu,
пример на setStyleSheet:
на входе в KMenu.setStyleSheet хочу передавать в класс переменные,
def setStyleSheet(bg, bd, bdcolor, bgcolor, bdsize):
...
на выходе в QMenu.setStyleSheet получить:
"QMenu {"
"background-color: %1;"
"border: %2px solid %3;"
"}" %1, %2, %3
Для этого нужно перенаправить в QMenu.
self.parent.setStyleSheet(*args, **kwargs) # не сработает
# (т.к. ссылается на родительский класс, а не на класс который изменяем)
QMenu.setStyleSheet(*args, **kwargs) # вроде как должно работать
self.parent.__init__(*args, **kwargs) # чем обусловлено применение?
И еще вопросы по теме: есть ли отличия и какие, при использовании
args, kwargs, *args, *kwargs, **kwargs, cnf={} ?
Как я понимаю **kw это сокращенно **kwargs, название не важно, важно понимание, а cnf={} как я понимаю это аналог *args или *a.
(cnf={} и **kw увидел в исходниках tkinter)
Что значат звездочки и что значит их количество?
Ответы (1 шт):
Я не знаю, правильно ли вас понял, но предложу попробовать. Если будет что-то не понятно - спросите.
import sys
from PyQt5.Qt import *
class Add_Dialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Dialog")
open_message = QLabel("Введите название действия:")
self.txt = QLineEdit()
self.path_icon = QLineEdit(placeholderText="Введите или выберите icon")
select_i = QPushButton('Выбрать иконку', clicked=self.select_icon)
save = QPushButton('Save', clicked=self.accept)
cancel = QPushButton('Cancel', clicked=self.reject)
grid = QGridLayout(self)
grid.setSpacing(10)
grid.addWidget(open_message, 0, 0)
grid.addWidget(self.txt, 0, 1)
grid.addWidget(self.path_icon, 1, 0)
grid.addWidget(select_i, 1, 1)
grid.addWidget(save, 2, 0)
grid.addWidget(cancel, 2, 1)
self.setFixedSize(self.sizeHint())
def select_icon(self):
fileName, _ = QFileDialog.getOpenFileName(
self,
"Выбрать иконку",
".",
"PNG Files (*.png);;JPG Files (*.jpg)"
)
self.path_icon.setText(fileName)
def save(self):
name = self.txt.text()
path_icon = self.path_icon.text()
return name, path_icon
class StyleSheet_Dialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("StyleSheet_Dialog")
label = QLabel("Введите bd:")
self.spinBox = QSpinBox()
self.spinBox.setMaximum(7)
self.spinBox.setProperty("value", 2)
self.bg = QLineEdit('#ABABAB', placeholderText="Введите или выберите bg")
s_bg = QPushButton('Выбрать bg', clicked=self.select_bg)
self.bdcolor = QLineEdit('#42240C', placeholderText="Введите или выберите bdcolor")
s_bdcolor = QPushButton('Выбрать bdcolor', clicked=self.select_bdcolor)
save = QPushButton('Save', clicked=self.accept)
cancel = QPushButton('Cancel', clicked=self.reject)
grid = QGridLayout(self)
grid.setSpacing(10)
grid.addWidget(label, 0, 0)
grid.addWidget(self.spinBox, 0, 1)
grid.addWidget(self.bg, 1, 0)
grid.addWidget(s_bg, 1, 1)
grid.addWidget(self.bdcolor, 2, 0)
grid.addWidget(s_bdcolor, 2, 1)
grid.addWidget(save, 3, 0)
grid.addWidget(cancel, 3, 1)
self.setFixedSize(self.sizeHint())
def select_bg(self):
dlg = QColorDialog(self)
if dlg.exec_():
self.bg.setText(dlg.currentColor().name())
def select_bdcolor(self):
dlg = QColorDialog(self)
if dlg.exec_():
self.bdcolor.setText(dlg.currentColor().name())
def save(self):
bd = self.spinBox.value()
bg = self.bg.text()
bdcolor = self.bdcolor.text()
return bg, bd, bdcolor
class Menu(QMenu):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setMinimumSize(150, 50)
self.bg = '#ABABAB'
self.bd = 2
self.bdcolor = '#42240C'
self._setStyleSheet(self.bg, self.bd, self.bdcolor)
def _addAction(self, text='New_Action',icon=""):
self.addAction(QIcon(icon), text)
def _setStyleSheet(self, bg, bd, bdcolor):
self.setStyleSheet('''
QMenu {{
background: {bg};
border: {bd}px solid {bdcolor};
}}
QMenu::item {{
color: #11144C;
font-size: 17px;
}}
QMenu::item:selected {{
background-color: #654321;
color: #fff;
}}
'''.format(bg=bg, bd=bd, bdcolor=bdcolor,))
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.centralWidget = QWidget()
self.setCentralWidget(self.centralWidget)
menuBar = self.menuBar()
self.menu = Menu("My_Menu", self)
self.menu.triggered.connect(self._add_handle)
self.menu.addAction(QIcon("im.png"), "Hello World")
menuBar.addMenu(self.menu)
self.label = QLabel("<h1>Hello World</h1>")
self.label.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
self.button = QPushButton('addAction', self)
self.button.clicked.connect(self.add_action)
self.button2 = QPushButton('setStyleSheet', self)
self.button2.clicked.connect(self.style_sheet_action)
layout = QGridLayout(self.centralWidget)
layout.addWidget(self.label, 0, 0, 1, 2)
layout.addWidget(self.button, 1, 0)
layout.addWidget(self.button2, 1, 1)
self.styleSheet_dialog = StyleSheet_Dialog()
def add_action(self):
add_dialog = Add_Dialog()
if add_dialog.exec_() == QDialog.Accepted:
name, path_icon = add_dialog.save()
if not name:
return
else:
return
self.menu._addAction(name, path_icon)
def style_sheet_action(self):
if self.styleSheet_dialog.exec_() == QDialog.Accepted:
bg, bd, bdcolor = self.styleSheet_dialog.save()
else:
return
self.menu._setStyleSheet(bg, bd, bdcolor)
def _add_handle(self, action):
print(f'action = {action.text()}')
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MainWindow()
w.resize(400, 300)
w.show()
sys.exit(app.exec_())




