Create Alert Dialogs with QMessageBox in PyQt6

While working on a Python desktop application, I needed to display various alert messages to users, from simple notifications to critical warnings. That’s when I discovered how useful QMessageBox is in PyQt6. The challenge was finding a way to create professional-looking message boxes that would effectively communicate with users.

In this guide, I will show you everything you need to know about QMessageBox in PyQt6, from basic implementation to customization.

I will cover multiple approaches with practical examples that you can start using in your applications today.

QMessageBox in PyQt6

Python QMessageBox is a dialog class in PyQt6 that provides a simple way to display information, ask questions, or warn users about something in your application. It’s essentially a pre-styled dialog window that can show:

  • Text messages
  • Standard icons (information, warning, critical, question)
  • Various button combinations
  • Return values based on user interaction

Unlike building custom dialog boxes from scratch, QMessageBox gives you a consistent look that follows the user’s operating system style.

Read QFontDialog in PyQt6: Create and Customize Font

Set Up Your PyQt6 Environment

Before we start creating message boxes, make sure you have PyQt6 installed:

pip install PyQt6

Let’s create a basic application structure that we’ll use throughout this tutorial:

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget
from PyQt6.QtCore import Qt

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("QMessageBox Demo")
        self.setGeometry(100, 100, 400, 300)

        # Create central widget and layout
        central_widget = QWidget()
        self.setCentralWidget(central_widget)

        layout = QVBoxLayout(central_widget)

        # We'll add our message box buttons here

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())

Method 1: Use Standard QMessageBox Static Methods

The easiest way to create message boxes is by using QMessageBox’s built-in static methods. These methods provide pre-configured dialogs for common scenarios.

Let’s add some buttons to our main window that will trigger different types of message boxes:

# Add this inside the MainWindow.__init__ after creating the layout
info_button = QPushButton("Show Information")
info_button.clicked.connect(self.show_info_message)
layout.addWidget(info_button)

warning_button = QPushButton("Show Warning")
warning_button.clicked.connect(self.show_warning_message)
layout.addWidget(warning_button)

error_button = QPushButton("Show Error")
error_button.clicked.connect(self.show_error_message)
layout.addWidget(error_button)

question_button = QPushButton("Show Question")
question_button.clicked.connect(self.show_question_message)
layout.addWidget(question_button)

Now, let’s implement the methods that will display each type of message box:

# Add these methods to the MainWindow class
from PyQt6.QtWidgets import QMessageBox

def show_info_message(self):
    QMessageBox.information(
        self,
        "Information",
        "Your tax return has been successfully submitted.",
        buttons=QMessageBox.StandardButton.Ok
    )

def show_warning_message(self):
    QMessageBox.warning(
        self,
        "Warning",
        "Your subscription will expire in 3 days. Please renew to avoid service interruption.",
        buttons=QMessageBox.StandardButton.Ok
    )

def show_error_message(self):
    QMessageBox.critical(
        self,
        "Error",
        "Failed to connect to the server. Please check your internet connection and try again.",
        buttons=QMessageBox.StandardButton.Ok
    )

def show_question_message(self):
    button = QMessageBox.question(
        self,
        "Confirm Action",
        "Are you sure you want to delete this file? This action cannot be undone.",
        buttons=QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
        defaultButton=QMessageBox.StandardButton.No
    )

    if button == QMessageBox.StandardButton.Yes:
        print("User chose to delete the file")
    else:
        print("User canceled the operation")

You can see the output in the screenshot below.

QMessageBox in PyQt6

These static methods are perfect for simple scenarios where you need standard message boxes with minimal customization.

Method 2: Create Custom QMessageBox Instances

When you need more control over your message boxes, you can create QMessageBox instances directly. This approach gives you access to additional customization options.

Let’s add a button for a custom message box:

# Add to MainWindow.__init__
custom_button = QPushButton("Show Custom Message Box")
custom_button.clicked.connect(self.show_custom_message)
layout.addWidget(custom_button)

And here’s the implementation:

def show_custom_message(self):
    msg_box = QMessageBox(self)
    msg_box.setWindowTitle("Payment Confirmation")
    msg_box.setText("Your payment of $199.99 was processed successfully.")
    msg_box.setInformativeText("Would you like to view your receipt?")
    msg_box.setIcon(QMessageBox.Icon.Information)

    # Add custom buttons
    view_button = msg_box.addButton("View Receipt", QMessageBox.ButtonRole.AcceptRole)
    email_button = msg_box.addButton("Email Receipt", QMessageBox.ButtonRole.ActionRole)
    later_button = msg_box.addButton("Later", QMessageBox.ButtonRole.RejectRole)

    msg_box.exec()

    # Handle button clicks
    clicked_button = msg_box.clickedButton()

    if clicked_button == view_button:
        print("User wants to view the receipt")
    elif clicked_button == email_button:
        print("User wants to email the receipt")
    else:
        print("User will check the receipt later")

You can see the output in the screenshot below.

PyQt6 QMessageBox

This approach gives you much more flexibility in creating message boxes tailored to your application’s needs.

Check out Work with QColorDialog in PyQt6

Method 3: Add Rich Text and Detailed Information

Sometimes you need to display more complex information in your message boxes, including formatted text and detailed explanations.

Let’s create a message box with rich text and detailed information:

# Add to MainWindow.__init__
detailed_button = QPushButton("Show Detailed Message")
detailed_button.clicked.connect(self.show_detailed_message)
layout.addWidget(detailed_button)

And the implementation:

def show_detailed_message(self):
    msg_box = QMessageBox(self)
    msg_box.setWindowTitle("Software Update Available")
    msg_box.setText("<b>Version 2.0.1 is now available!</b>")
    msg_box.setInformativeText("Would you like to update now or later?")

    # Add detailed text that appears when "Show Details" is clicked
    details = """
    <h3>What's New in Version 2.0.1:</h3>
    <ul>
        <li>Fixed critical security vulnerability in login system</li>
        <li>Improved performance for large data processing</li>
        <li>Added new reporting features for financial analysis</li>
        <li>Updated UI with new dark mode support</li>
    </ul>
    <p>The update requires approximately 5 minutes to install and will restart your application.</p>
    """
    msg_box.setDetailedText(details)
    msg_box.setTextFormat(Qt.TextFormat.RichText)

    # Add buttons
    msg_box.addButton("Update Now", QMessageBox.ButtonRole.AcceptRole)
    msg_box.addButton("Remind Me Later", QMessageBox.ButtonRole.RejectRole)

    msg_box.exec()

You can see the output in the screenshot below.

Create Alert Dialogs with QMessageBox in PyQt6

This method is ideal for providing comprehensive information to users without confusing them initially.

Method 4: Create Confirmation Dialogs with QMessageBox

One common use case for QMessageBox is to create confirmation dialogs that ask users to confirm potentially risky actions.

Let’s add a button for a confirmation dialog:

# Add to MainWindow.__init__
confirm_button = QPushButton("Delete Account")
confirm_button.clicked.connect(self.confirm_account_deletion)
layout.addWidget(confirm_button)

And here’s the implementation:

def confirm_account_deletion(self):
    msg_box = QMessageBox(self)
    msg_box.setWindowTitle("Confirm Account Deletion")
    msg_box.setText("You are about to permanently delete your account.")
    msg_box.setInformativeText("This action cannot be undone. All your data will be permanently lost.")
    msg_box.setIcon(QMessageBox.Icon.Warning)

    # Set default focus to the cancel button
    msg_box.setStandardButtons(QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.Cancel)
    msg_box.setDefaultButton(QMessageBox.StandardButton.Cancel)

    # Make the Yes button red to indicate danger
    yes_button = msg_box.button(QMessageBox.StandardButton.Yes)
    yes_button.setText("Delete My Account")
    yes_button.setStyleSheet("background-color: #d9534f; color: white;")

    result = msg_box.exec()

    if result == QMessageBox.StandardButton.Yes:
        # In a real application, you would delete the account here
        QMessageBox.information(
            self,
            "Account Deleted",
            "Your account has been permanently deleted. We're sorry to see you go."
        )

This pattern is extremely useful for protecting users from accidental destructive actions.

Read How to Use QInputDialog in PyQt6

Method 5: Display Progress and Non-Modal Message Boxes

Sometimes you need to show a message while allowing users to continue interacting with your application. This is where non-modal message boxes come in handy.

Let’s add a button for a non-modal message:

# Add to MainWindow.__init__
nonmodal_button = QPushButton("Start Background Task")
nonmodal_button.clicked.connect(self.start_background_task)
layout.addWidget(nonmodal_button)

And the implementation:

def start_background_task(self):
    self.progress_msg = QMessageBox(self)
    self.progress_msg.setWindowTitle("Processing")
    self.progress_msg.setText("Analyzing your financial data...")
    self.progress_msg.setInformativeText("This may take a few moments. You can continue working with the application.")
    self.progress_msg.setIcon(QMessageBox.Icon.Information)
    self.progress_msg.setStandardButtons(QMessageBox.StandardButton.NoButton)

    # Make the message box non-modal
    self.progress_msg.setModal(False)
    self.progress_msg.show()

    # In a real application, you would start a QThread here
    # For demonstration, we'll use a simple timer
    from PyQt6.QtCore import QTimer
    QTimer.singleShot(5000, self.finish_background_task)

def finish_background_task(self):
    # Close the progress message
    self.progress_msg.close()

    # Show completion message
    QMessageBox.information(
        self,
        "Analysis Complete",
        "Your financial data has been analyzed. View the report in the Reports tab."
    )

This approach is perfect for long-running operations where you want to keep users informed without blocking their interaction with the application.

I’ve found that message boxes are an essential part of creating user-friendly applications. They provide important feedback, confirmations, and warnings that help guide users through your application safely and efficiently.

When implementing QMessageBox in your applications, remember that the best message boxes are clear, concise, and provide users with the information they need to make decisions. Over-using message boxes can lead to alert fatigue, where users start dismissing them without reading.

Check out QCalendarWidget in PyQt6

Handle Alert Fatigue with Smart Message Boxes

One way to reduce alert fatigue is through collaborative alert sharing and smarter message box implementation. Here are some tips that I’ve learned over the years:

  1. Consolidate related messages – Instead of showing multiple alerts, group them when possible
  2. Use appropriate severity levels – Not everything is critical; use information icons for non-urgent messages
  3. Provide clear actions – Every message box should make it obvious what action the user can take
  4. Remember user preferences – Add “Don’t show again” options for informational messages
  5. Time your messages wisely – Avoid interrupting users in the middle of important tasks

Let me show you how to implement a “Don’t show again” feature:

def show_tip_message(self):
    # Check if user has opted out of tips
    from PyQt6.QtCore import QSettings
    settings = QSettings("YourCompany", "YourApp")
    
    if settings.value("show_tips", True, type=bool):
        msg_box = QMessageBox(self)
        msg_box.setWindowTitle("Productivity Tip")
        msg_box.setText("Did you know you can use keyboard shortcuts?")
        msg_box.setInformativeText("Press Ctrl+S to save, Ctrl+O to open files, and Ctrl+P to print.")
        msg_box.setIcon(QMessageBox.Icon.Information)
        
        # Add a "Don't show again" checkbox
        from PyQt6.QtWidgets import QCheckBox
        dont_show = QCheckBox("Don't show tips again")
        msg_box.setCheckBox(dont_show)
        
        msg_box.exec()
        
        # Save preference if "Don't show again" was checked
        if dont_show.isChecked():
            settings.setValue("show_tips", False)

Conclusion

QMessageBox in PyQt6 is a versatile tool for creating dialog boxes that effectively communicate with your users.

The methods that I explained in this tutorial are using QMessageBox static, creating a custom QMessageBox instance, adding rich text and dialogs with QMessageBox, creating confirmation dialogs with QMessageBox, and displaying progress and non-model message boxes.

PyQt6-related articles:

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.