I know many of you are just looking for some reference code to copy so I put that here at the top, but if you want to learn more, a detailed explanation can be found in the video above and in the text below.
import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton,
QMessageBox)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("My Popup Window")
self.button = QPushButton("Popup!")
self.button.clicked.connect(self.on_button_press)
self.setCentralWidget(self.button)
def on_button_press(self):
button = QMessageBox.question(
self,
"Simple QMessageBox",
"This is a QMessageBox"
)
if button == QMessageBox.Yes:
print("Yes")
else:
print("No")
def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
if __name__ == '__main__':
main()
Environment Setup
I use Python virtual environments for my PyQt development. If you have never worked with one, see my article covering the basics here. For this project I just pip install
ed PyQt5
.
A Simple QMessageBox Popup
Using the QMessageBox class is a quick way to get a pop-up box working. Below is a simple example program that creates a pop-up that displays a message:
import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton,
QMessageBox)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("My Popup")
self.button = QPushButton("Open QMessageBox")
self.button.clicked.connect(self.on_button_press)
self.setCentralWidget(self.button)
def on_button_press(self):
"""This is a simple QMessageBox"""
message_box = QMessageBox(self)
message_box.setWindowTitle("Simple QMessageBox")
message_box.setText("This is a QMessageBox. ")
message_box.exec()
def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
if __name__ == '__main__':
main()
Let’s talk through the code.
import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton,
QMessageBox)
Lines 1-3 pull in the modules and classes we need.
def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
if __name__ == '__main__':
main()
These lines are common through most PyQt applications I have built. We have a main()
function that is run when this file is executed. It creates a QApplication
, and a MainWindow
that is shown and the QApplication
is executed.
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("My Popup")
self.button = QPushButton("Open QMessageBox")
self.button.clicked.connect(self.on_button_press)
self.setCentralWidget(self.button)
The MainWindow
class overrides QMainWindow
so we can customize the window. We call it’s parent’s constructor with super().init()
and we set the window title for the main window as "My Popup"
.
We create a QPushButton
to trigger the pop-up. The button has the text "Open QMessageBox"
.
On line 12 we set it up so when the button is clicked, the self.on_button_press method
is called.
Lastly we add the button to the window by setting it as the central widget.
def on_button_press(self):
"""This is a simple QMessageBox"""
message_box = QMessageBox(self)
message_box.setWindowTitle("Simple QMessageBox")
message_box.setText("This is a QMessageBox. ")
message_box.exec()
Now to the QMessageBox
! On line 17 we create a QMessageBox
, passing in self
as the parent.
On line 18, we set the title of the QMessageBox
to "Simple QMessageBox"
.
Note: If you are working on a Mac and you are missing the title on the pop-up, as mentioned in the Qt documentation for setWindowTitle():
On macOS, the window title is ignored (as required by the macOS Guidelines).
On line 19, we set the text for the dialog, and on line 20, we show it by running exec()
.
Below are what the window with the button, and the pop-up look like:


Note: The pop-up created with QMessageBox is a modal dialog. That means that the user cannot interact with the rest of the program until the dialog closes.
Capturing Input with QMessageBox
Making a QMessageBox with multiple buttons and capturing which one the user clicks is pretty straightforward. Its mostly the same code as the previous example. The full example is below, and under that we will cover the changes line by line.
import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton,
QMessageBox)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("My Popup")
self.button = QPushButton("Open QMessageBox")
self.button.clicked.connect(self.on_button_press)
self.setCentralWidget(self.button)
def on_button_press(self):
"""This is a simple QMessageBox"""
message_box = QMessageBox(self)
message_box.setWindowTitle("Yes/No QMessageBox")
message_box.setText("This is a QMessageBox. Yes or No?")
message_box.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
message_box.setIcon(QMessageBox.Question)
button = message_box.exec()
if button == QMessageBox.Yes:
print("Yes!")
else:
print("No!")
def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
if __name__ == '__main__':
main()
The only part that changes is the on_button_press
method. Let’s take a look at that.
def on_button_press(self):
"""This is a simple QMessageBox"""
message_box = QMessageBox(self)
message_box.setWindowTitle("Yes/No QMessageBox")
message_box.setText("This is a QMessageBox. Yes or No?")
Like the previous example, we create a QMessageBox object, we set the window title, and set the text.
message_box.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
What is new is that we use the setStandardButtons()
method to add what buttons we want to the QMessageBox()
. The buttons you can pass to this method, are represented by constants. When you want to do multiple buttons, you OR them together with the | character. A full list of QMessageBox
buttons for PyQt5 can be seen below:
Constant | Button Text |
---|---|
QMessageBox.Abort | “Abort” |
QMessageBox.Apply | “Apply” |
QMessageBox.Cancel | “Cancel” |
QMessageBox.Close | “Close” |
QMessageBox.Discard | “Discard” |
QMessageBox.Help | “Help” |
QMessageBox.Ignore | “Ignore” |
QMessageBox.No | “No” |
QMessageBox.NoButton | *An invalid button |
QMessageBox.NoToAll | “No to All” |
QMessageBox.Ok | “Ok” |
QMessageBox.Open | “Open” |
QMessageBox.Reset | “Reset” |
QMessageBox.RestoreDefaults | “Restore Defaults” |
QMessageBox.Retry | “Retry” |
QMessageBox.Save | “Save” |
QMessageBox.SaveAll | “Save All” |
QMessageBox.Yes | “Yes” |
QMessageBox.YesToAll | “Yes to All” |
You can add icons to your QMessageBox
. We add a question icon on line 21.
message_box.setIcon(QMessageBox.Question)
A list of all built in QMessageBox
icons is listed below for PyQt5:
Constant | Icon |
---|---|
QMessageBox.Critical | ![]() |
QMessageBox.Information | ![]() |
QMessageBox.NoIcon | This is for having no icon. |
QMessageBox.Question | ![]() |
QMessageBox.Warning | ![]() |
The last lines of the method are for displaying it, and capturing the button the user clicks on.
Line 22 shows the QMessageBox with the exec() methos, and it returns the button clicked on as one of button constants mentioned above. We then print to the terminal based on which button was pressed.
button = message_box.exec()
if button == QMessageBox.Yes:
print("Yes!")
else:
print("No!")
And here is what the final pop-up looks like:

Using Built-In QMessageBox Types
It turns out we can make the same pop-up in even less code using one of QMessageBox’s builtin methods. The full example is below, and under that we will cover the changes line by line.
import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton,
QMessageBox)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("My Popup")
self.button = QPushButton("Open QMessageBox")
self.button.clicked.connect(self.on_button_press)
self.setCentralWidget(self.button)
def on_button_press(self):
"""This is using the builtin QMessageBoxes"""
title = "Yes/No QMessageBox"
text = "This is a QMessageBox. Yes or No?"
button = QMessageBox.question(self, title, text)
if button == QMessageBox.Yes:
print("Yes!")
else:
print("No!")
def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
if __name__ == '__main__':
main()
The code is largely the same. The difference is in the on_button_press()
method, specifically lines 17-19:
def on_button_press(self):
"""This is using the builtin QMessageBoxes"""
title = "Yes/No QMessageBox"
text = "This is a QMessageBox. Yes or No?"
button = QMessageBox.question(self, title, text)
As seen above, we can use the QMessageBox.question
() to set the title, set the text, create the Yes/No buttons, show the pop-up, and return the button. The rest of the code is the same.
There are a few of these that do all the heavy lifting for you. A list of them, what they look like, and example code for each can be seen below:
about()

Displays a simple about pop-up with title, text, icon, and “Ok” button. It looks for the icon in this list of places, going to the next option if not found:
parent.icon()
icon()
on the top level widget that contains parenticon()
on the active window- The information icon.
Show code example…
import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton,
QMessageBox)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("My Popup")
self.button = QPushButton("Open QMessageBox")
self.button.clicked.connect(self.on_button_press)
self.setCentralWidget(self.button)
def on_button_press(self):
"""About"""
title = "About"
text = "This is the about text."
QMessageBox.about(self, title, text)
def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
if __name__ == '__main__':
main()
aboutQt()

Displays a pop-up about the current Qt version being used with the given title.
Show code example…
import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton,
QMessageBox)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("My Popup")
self.button = QPushButton("Open QMessageBox")
self.button.clicked.connect(self.on_button_press)
self.setCentralWidget(self.button)
def on_button_press(self):
"""About Qt"""
title = "About Qt"
QMessageBox.aboutQt(self, title)
def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
if __name__ == '__main__':
main()
critical()

Opens a critical pop-up with the given title, and text. By default an “Ok” button is displayed but it can be passed any combination of buttons. You can also set what the default button is.
Show code example…
import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton,
QMessageBox)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("My Popup")
self.button = QPushButton("Open QMessageBox")
self.button.clicked.connect(self.on_button_press)
self.setCentralWidget(self.button)
def on_button_press(self):
"""Critical"""
title = "Critical!"
text = "This is critical! Do you understand?"
buttons = QMessageBox.Yes | QMessageBox.No
default_button = QMessageBox.No
QMessageBox.critical(self, title, text, buttons, default_button)
def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
if __name__ == '__main__':
main()
information()

Opens an information pop-up with the given title, and text. By default an “Ok” button is displayed but it can be passed any combination of buttons. You can also set what the default button is.
Show code example…
import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton,
QMessageBox)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("My Popup")
self.button = QPushButton("Open QMessageBox")
self.button.clicked.connect(self.on_button_press)
self.setCentralWidget(self.button)
def on_button_press(self):
"""Information"""
title = "Information"
text = "Do you understand the information?"
buttons = QMessageBox.Yes | QMessageBox.No
default_button = QMessageBox.No
QMessageBox.information(self, title, text, buttons, default_button)
def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
if __name__ == '__main__':
main()
question()

Opens a question pop-up with the given title, and text. By default a “Yes” and a “No” button are displayed but it can be passed any combination of buttons. You can also set what the default button is.
Show code example…
import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton,
QMessageBox)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("My Popup")
self.button = QPushButton("Open QMessageBox")
self.button.clicked.connect(self.on_button_press)
self.setCentralWidget(self.button)
def on_button_press(self):
"""Question"""
title = "Question"
text = "Do you understand the question?"
buttons = QMessageBox.Yes | QMessageBox.No
default_button = QMessageBox.No
QMessageBox.question(self, title, text, buttons, default_button)
def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
if __name__ == '__main__':
main()
warning()

Opens a warning pop-up with the given title, and text. By default an “Ok” button is displayed but it can be passed any combination of buttons. You can also set what the default button is.
Show code example…
import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton,
QMessageBox)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("My Popup")
self.button = QPushButton("Open QMessageBox")
self.button.clicked.connect(self.on_button_press)
self.setCentralWidget(self.button)
def on_button_press(self):
"""Warning"""
title = "Warning"
text = "Do you understand the warning?"
buttons = QMessageBox.Yes | QMessageBox.No
default_button = QMessageBox.No
QMessageBox.warning(self, title, text, buttons, default_button)
def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
if __name__ == '__main__':
main()