How to Show a QMenu Title in PyQt6

Adding visible titles to your context menus using QLabel, QWidgetAction, and other approaches
Heads up! You've already completed this tutorial.

If you've ever tried to set a title on a QMenu in PyQt6, you've probably noticed something frustrating: calling setTitle() on a menu doesn't actually display a title on the popup itself. The title property on QMenu is used for something else entirely — it's the text that appears when the menu is added to a QMenuBar (like "File", "Edit", etc.). When you show a QMenu as a standalone context menu, that title is invisible.

So how do you show a visible heading at the top of a context menu? There are a few approaches, each with their own trade-offs. In this tutorial, we'll walk through all of them and finish with the most flexible solution: embedding a QLabel widget directly in the menu using QWidgetAction.

Why setTitle() Doesn't Work

When you create a QMenu and call setTitle(), you're setting the label that would appear on a menu bar. For example:

python
menu = QMenu()
menu.setTitle("My Menu")

If you added this menu to a QMenuBar, you'd see "My Menu" as a clickable item on the bar. But when you show this menu as a popup context menu (using .show() or .exec()), that title is nowhere to be seen.

This catches a lot of people off guard, but once you know why it works this way, you can reach for the right solution.

Using addSection()

Qt provides a built-in method called addSection() that's designed to add labeled section headers to a menu. You might think this is exactly what you need — and depending on your platform and theme, it might be.

python
menu = QMenu()
menu.addSection("My Menu Title")
menu.addAction("Option 1")
menu.addAction("Option 2")

The catch is that addSection() renders differently depending on the platform style. On macOS and Windows native themes, it often looks identical to a plain separator line — the text simply doesn't show up.

The one reliable way to make addSection() visible is to use the Fusion style, which is Qt's built-in cross-platform theme:

python
app = QApplication(sys.argv)
app.setStyle("Fusion")

With Fusion active, addSection() displays the section text alongside a separator line, which looks quite nice. The downside is that Fusion doesn't match the native look and feel of any operating system, so your entire application will look slightly different from other apps on the user's desktop.

Packaging Python Applications with PyInstaller by Martin Fitzpatrick — This step-by-step guide walks you through packaging your own Python applications from simple examples to complete installers and signed executables.

Get the book

Using a Disabled Action

A simpler workaround is to add a regular action and then disable it. A disabled action shows its text but appears grayed out and can't be clicked:

python
menu = QMenu()
title_action = menu.addAction("My Menu Title")
title_action.setDisabled(True)
menu.addSeparator()
menu.addAction("Option 1")
menu.addAction("Option 2")

This works on all platforms and themes. The text shows up, and users can't accidentally click on it. However, it looks like a disabled menu item, which could be confusing — users might wonder what they need to do to enable it.

Using a QLabel with QWidgetAction

The most flexible approach is to embed a QLabel widget directly into the menu using QWidgetAction. This lets you fully control the appearance of the title — you can center it, make it bold, change its background color, and more.

Here's how it works. First, create a QLabel with the text you want:

python
from PyQt6.QtWidgets import QLabel, QWidgetAction, QSizePolicy
from PyQt6.QtCore import Qt

label = QLabel("My Menu Title")
label.setAlignment(Qt.AlignCenter)
label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

Then wrap the label in a QWidgetAction and add it to the menu. Note that the parent of the QWidgetAction should be the menu itself (not the label) — this ensures proper memory management and avoids crashes:

python
menu = QMenu()

widget_action = QWidgetAction(menu)
widget_action.setDefaultWidget(label)
menu.addAction(widget_action)

menu.addSeparator()
menu.addAction("Option 1")
menu.addAction("Option 2")

You can style the label however you like. For example, to make it bold with a colored background:

python
label.setStyleSheet("font-weight: bold; background-color: #e0e0e0; padding: 4px;")

This approach works reliably across all platforms and themes, and gives you complete control over how the title looks.

Complete Working Example

Here's a full example that demonstrates all three approaches side by side. Right-click anywhere in the window to see a context menu with a QLabel-based title. You can uncomment the alternative approaches to compare them.

python
import sys
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import (
    QApplication, QMainWindow, QMenu, QLabel,
    QWidgetAction, QSizePolicy
)


class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.setWindowTitle("QMenu Title Example")
        self.resize(400, 300)

        label = QLabel("Right-click anywhere in this window")
        label.setAlignment(Qt.AlignCenter)
        self.setCentralWidget(label)

    def contextMenuEvent(self, event):
        menu = QMenu(self)

        # --- Approach 1: QLabel with QWidgetAction (recommended) ---
        title_label = QLabel("My Menu Title")
        title_label.setAlignment(Qt.AlignCenter)
        title_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        title_label.setStyleSheet(
            "font-weight: bold; padding: 4px;"
        )

        title_action = QWidgetAction(menu)
        title_action.setDefaultWidget(title_label)
        menu.addAction(title_action)

        # --- Approach 2: Disabled action (uncomment to try) ---
        # title_action = menu.addAction("My Menu Title")
        # title_action.setDisabled(True)

        # --- Approach 3: addSection (uncomment to try, works best with Fusion) ---
        # menu.addSection("My Menu Title")

        menu.addSeparator()
        menu.addAction("Select All")
        menu.addAction("Copy")
        menu.addAction("Paste")
        menu.addSeparator()
        menu.addAction("Settings...")

        menu.exec(event.globalPos())


if __name__ == "__main__":
    app = QApplication(sys.argv)

    # Uncomment the next line to try the Fusion style with addSection()
    # app.setStyle("Fusion")

    window = MainWindow()
    window.show()
    sys.exit(app.exec())

When you run this and right-click in the window, you'll see a context menu with a bold, centered title at the top.

The QWidgetAction approach is the most versatile because you have full control over the widget. You could swap the QLabel for any widget — even a small layout with an icon and text, if you wanted to get creative.

Summary

The title property on QMenu is meant for menu bar display, not for context menu headings. To show a visible title on a popup menu, you have three options:

  • addSection() — built-in but only visible with certain styles (like Fusion).
  • Disabled action — simple but looks like a grayed-out menu item.
  • QWidgetAction with a QLabel — looks like a heading and gives you full control over the title's appearance.

Usually QWidgetAction is the one you want to go with. For more on building menus, toolbars, and actions in PyQt6, see our tutorial on Actions, Toolbars & Menus in PyQt6. If you're building custom widgets like styled labels or other UI elements, you may also find our guide to creating your own custom widgets in PyQt6 helpful.

Over 15,000 developers have bought Create GUI Applications with Python & Qt!
Create GUI Applications with Python & Qt6
Get the book

Downloadable ebook (PDF, ePub) & Complete Source code

Well done, you've finished this tutorial! Mark As Complete
[[ user.completed.length ]] completed [[ user.streak+1 ]] day streak
Martin Fitzpatrick

How to Show a QMenu Title in PyQt6 was written by Martin Fitzpatrick.

Martin Fitzpatrick has been developing Python/Qt apps for 8 years. Building desktop applications to make data-analysis tools more user-friendly, Python was the obvious choice. Starting with Tk, later moving to wxWidgets and finally adopting PyQt. Martin founded PythonGUIs to provide easy to follow GUI programming tutorials to the Python community. He has written a number of popular Python books on the subject.