Customize QMenu display with QProxyStyle
Charles
peacech at gmail.com
Tue Jun 10 02:12:30 BST 2025
I tried it with the fusion style and it seems that there are some points
where I was wrong:
(1) the proxy style doesn't automatically use the application style,
instead it uses the default style
(2) the drawControl of fusion style doesn't use drawItemText for drawing
the text
Anyway, here is what works for me (which works with the default or the
fusion style)
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QApplication, QMainWindow, QMenu, QProxyStyle,
QStyle, QStyleOptionMenuItem
class ProxyStyle(QProxyStyle):
# uncomment this to use the fusion style
# def __init__(self):
# super().__init__('fusion')
def drawControl(self, element, option, painter, widget):
text = option.text
if element == QStyle.ControlElement.CE_MenuItem:
option.text = ''
super().drawControl(element, option, painter, widget)
if element == QStyle.ControlElement.CE_MenuItem:
painter.drawText(option.rect.adjusted(0, 0, -10, 0),
Qt.AlignmentFlag.AlignVCenter | Qt.AlignmentFlag.AlignRight, text)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
file_menu = QMenu('File', self)
file_menu.addAction('New')
file_menu.addAction('Open')
file_menu.addAction('Transform')
file_menu.setStyle(ProxyStyle())
self.menuBar().addMenu(file_menu)
if __name__ == '__main__':
app = QApplication([])
# app.setStyle('fusion') # uncomment this to use the fusion style
main_window = MainWindow()
main_window.show()
app.exec()
On Tue, Jun 10, 2025 at 3:36 AM John Sturtz <john at sturtz.org> wrote:
> ------ Original Message ------
> From "Charles" <peacech at gmail.com>
> To "John Sturtz" <john at sturtz.org>
> Cc pyqt at riverbankcomputing.com
> Date 6/9/2025 12:20:29 PM
> Subject Re: Re[2]: Customize QMenu display with QProxyStyle
>
> QProxyStyle automatically proxies to the used application style.
>
> I wondered if that mightn't be the case. That's fortunate.
>
> If you want rounded corners you need to port the whole C code in the
> OS style plugin that draws the menu item.
>
> Alternatively, use the fusion style which should be OS independent.
> With fusion style, overriding drawItemText should work.
>
> Actually, I didn't particularly want rounded corners, although I'm not
> sure I care that much.
>
> If I set fusion for the whole app [app.setStyle('Fusion')], I don't get
> rounded corners by default. But if I apply the proxy style, then I do.
> If I don't set fusion for the whole app, I get rounded corners either way.
>
> And here's another interesting factoid: It seems that just the act of
> trying to create a proxy style based on the existing style causes a crash.
> This statement:
>
> self.style = Style(file_menu.style())
>
> makes the app crash on exit, even if I never actually use the created
> proxy style.
>
> Anyway, thanks again for your help. All this gives me plenty to go
> forward with.
>
> /John
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20250610/a8301811/attachment.htm>
More information about the PyQt
mailing list