Search code examples
pythonqtqwidgetpyside6qmessagebox

Why can't I change the window icon on a QMessageBox with setIcon in PySide6?


I have been following an online tutorial and corresponding book by Martin Fitzpatrick to get familiar with PySide6. On the topic of message boxes, it is mentioned there that we can change the icon that appears on the pop up window, but no matter what I try, no matter what specific icon I request, the "default" one (a python rocket for me) keeps popping up.

Default icon appearing on QMessageBox even when Question is requested

This is the code I am using so far

import sys

from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QMessageBox

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

        self.setWindowTitle("My App")

        button = QPushButton("Press me for a dialog!")
        button.clicked.connect(self.button_clicked)
        self.setCentralWidget(button)

    def button_clicked(self, s):
        dlg = QMessageBox()
        dlg.setIcon(QMessageBox.Question)
        button = dlg.exec()

        if button == QMessageBox.Ok:
            print("OK!")

app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()

As you can see, the dlg variable refers to a recently constructed QMessageBox() to which I attempt to set a specific icon among the provided ones (QMessageBox.Question).

What am I missing? I have also tried with QMessageBox.Icons.Question since I saw that suggested online, but to no success.

Any help would be appreciated.


Solution

  • As Musicamante's comments, it is a Qt bug. You can see an old issue which failed to attract core developers.

    You can disable a preference for a native dialog, like this.

    from PySide6.QtCore import Qt
    ...
    
    class MainWindow(QMainWindow):
        ...
        def button_clicked(self, s):
            app.setAttribute(Qt.ApplicationAttribute.AA_DontUseNativeDialogs, True)
            dlg = QMessageBox()
            dlg.setIcon(QMessageBox.Question)
            button = dlg.exec()
            app.setAttribute(Qt.ApplicationAttribute.AA_DontUseNativeDialogs, False)
    ...
    app = QApplication(sys.argv)
    ...
    

    It's up to you whether to avoid native dialogs or not. If a native dialog works well, it would be better to use it because it has more features of the underlying OS. For the QFileDialog API, they provide a special DontUseNativeDialog option. (I guess there were some complaints about a native file dialog.)