Вывод ошибки pyqt5

При использовании PyQt5, например при нажатии кнопки к которой привязана функция, если что-либо в ней (функции) идет не так - программа “падает” и ничего не выдается об ошибке в консоль IDE (в моем случае PyCharm), возможно кто знает, как это исправить?

Уведомления

  • Начало
  • » Python для новичков
  • » Вывод ошибки от PyQt5 в консоль

#1 Авг. 1, 2017 09:41:14

Вывод ошибки от PyQt5 в консоль

При использовании PyQt5, например при нажатии кнопки к которой привязана функция, если что-либо в ней (функции) идет не так — программа “падает” и ничего не выдается об ошибке в консоль IDE (в моем случае PyCharm), возможно кто знает, как это исправить?

upd (решение):

https://stackoverflow.com/questions/34363552/python-process-finished-with-exit-code-1-when-using-pycharm-and-pyqt5

 # Back up the reference to the exceptionhook
sys._excepthook = sys.excepthook
def my_exception_hook(exctype, value, traceback):
    # Print the error and traceback
    print(exctype, value, traceback)
    # Call the normal Exception hook after
    sys._excepthook(exctype, value, traceback)
    sys.exit(1)
# Set the exception hook to our wrapping function
sys.excepthook = my_exception_hook
 try:
    sys.exit(app.exec_())
except:
    print("Exiting")

Отредактировано gmaksim (Авг. 1, 2017 12:37:16)

Офлайн

  • Пожаловаться

#2 Авг. 1, 2017 10:24:29

Вывод ошибки от PyQt5 в консоль

Трудно представить, как можно неправильно запустить программу в пайшарме, но кажется, вам это удалось

Офлайн

  • Пожаловаться

#3 Авг. 1, 2017 10:25:54

Вывод ошибки от PyQt5 в консоль

Хотя, может быть просто не туда глядите

Офлайн

  • Пожаловаться

#4 Авг. 1, 2017 10:39:43

Вывод ошибки от PyQt5 в консоль

Да как бы не так.
print в функциях работают и выдают информацию (“навесил” для теста). Пример работы консоли и “падения” программы в приложении.

По коду — вызывается класс, в классе идут методы один за другим, в них вызывается GUI другими методами с разными параметрами. Есть метод для сохранения данных в БД, вот там и падает, и это точно какая-то особенность использования в качестве GUI — PyQt5 — так как при использовании tkinter — условно при нажатии кнопки запуска функции сохранения в БД в консоль выводило ошибку, почему она не срабатывала, тут же просто “падает”.

Отредактировано gmaksim (Авг. 1, 2017 10:43:56)

Прикреплённый файлы:
attachment 2.PNG (18,8 KБ)

Офлайн

  • Пожаловаться

#5 Авг. 1, 2017 10:47:32

Вывод ошибки от PyQt5 в консоль

gmaksim
При использовании PyQt5, например при нажатии кнопки к которой привязана функция, если что-либо в ней (функции) идет не так — программа “падает” и ничего не выдается об ошибке в консоль IDE (в моем случае PyCharm), возможно кто знает, как это исправить?
Онлайн

есть такое и именно в PyQt5. это особенность сборки походу, в С++ такое бывает при сегфолте или нуль-пойнтере. можно из терминала запускать типа python -v my_script

Офлайн

  • Пожаловаться

#6 Авг. 1, 2017 10:57:29

Вывод ошибки от PyQt5 в консоль

gmaksim
Ну блин, вы так вопрос задаете “ничего не выдается об ошибке в консоль IDE” как будто у вас нет сообщения об ошибке именно в терминале пайшарма, а другом терминале — все нормально.
PyQt — это набор питоньих обвязок над бинарниками Qt, если что-то “падает” при выполнении этого бинарного кода мы никогда не получим питоньего трейсбэка. Просто, примите это как должное.

Офлайн

  • Пожаловаться

#7 Авг. 1, 2017 11:17:21

Вывод ошибки от PyQt5 в консоль

vic57
есть такое и именно в PyQt5. это особенность сборки походу, в С++ такое бывает при сегфолте или нуль-пойнтере. можно из терминала запускать типа python -v my_script

Получилось, только теперь падает на строчке:

conn = sqlite3.connect(‘DATA//db.sqlite’)
sqlite3.OperationalError: unable to open database file

Наверно надо поменять на абсолютный путь?

FishHook
PyQt — это набор питоньих обвязок над бинарниками Qt, если что-то “падает” при выполнении этого бинарного кода мы никогда не получим питоньего трейсбэка. Просто, примите это как должное.

Как-то так и думал, но надеялся, что может есть пути обхода.
python -v my_script похоже на то.

Отредактировано gmaksim (Авг. 1, 2017 11:17:55)

Офлайн

  • Пожаловаться

#8 Авг. 1, 2017 11:20:42

Вывод ошибки от PyQt5 в консоль

gmaksim
sqlite3.OperationalError: unable to open database file

это уже не Qt ошибка

Офлайн

  • Пожаловаться

#9 Авг. 1, 2017 11:36:42

Вывод ошибки от PyQt5 в консоль

vic57
это уже не Qt ошибка

Угу, я и не имел ввиду, что это Qt ошибка, разобрался, действительно все выводит. Еще раз спасибо.

FishHook
Однако ‘python -v my_script’ (из терминала) все отлавливает (перед “падением”).

Отредактировано gmaksim (Авг. 1, 2017 11:37:10)

Офлайн

  • Пожаловаться

#10 Авг. 1, 2017 11:41:23

Вывод ошибки от PyQt5 в консоль

gmaksim
действительно все отлавливает

Что “всё”? Вы же понимаете, что невозможно показать построчный вывод ошибки в скомпилированной сишной библиотеке. Ваша ошибка возникает явно в питоньем коде, поэтому она и отлавливается.

Офлайн

  • Пожаловаться

  • Начало
  • » Python для новичков
  • » Вывод ошибки от PyQt5 в консоль

0 / 0 / 1

Регистрация: 03.02.2015

Сообщений: 81

1

12.05.2017, 03:58. Показов 6153. Ответов 10


PyQt5 при возникновении ошибки просто завершает работу программы, а хотелось бы посмотреть что ему не понравилось…
Как включить отображение ошибок?
(а то я скоро экстрасенсом стану)

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



2739 / 2342 / 620

Регистрация: 19.03.2012

Сообщений: 8,832

12.05.2017, 05:19

2

Глобальный перехватчик делаешь в месте запуска программы и в обработчике показываешь ошибку возникшую, а потом закрываешь прогу.



0



kak_ivan

0 / 0 / 1

Регистрация: 03.02.2015

Сообщений: 81

13.05.2017, 02:17

 [ТС]

3

Цитата
Сообщение от alex925
Посмотреть сообщение

Глобальный перехватчик делаешь в месте запуска программы

Если так, то не работает(

Python
1
2
3
4
5
6
7
8
9
10
11
if __name__ == "__main__":
    import sys
    try:
        app = QtWidgets.QApplication(sys.argv)
        MainWindow = QtWidgets.QMainWindow()
        ui = Ui_MainWindow()
        ui.setupUi(MainWindow)
        MainWindow.show()
        sys.exit(app.exec_())
    except Exception as e:
        raise e



0



2739 / 2342 / 620

Регистрация: 19.03.2012

Сообщений: 8,832

13.05.2017, 10:12

4

kak_ivan, так ты тут и не делаешь отображения ошибки. Ты ее поймал и опять кинул дальше.



0



kak_ivan

0 / 0 / 1

Регистрация: 03.02.2015

Сообщений: 81

13.05.2017, 21:58

 [ТС]

5

Цитата
Сообщение от alex925
Посмотреть сообщение

так ты тут и не делаешь отображения ошибки.

http://pep8.ru/doc/tutorial-2.6/9.html

Оператор raise позволяет программисту принудительно породить исключение. Например:

Python
1
2
3
4
>>> raise NameError, 'ПриветТам'
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
NameError: ПриветТам

Я принудительно порождаю исключение которое отловил try:except:
А так как это не работает, значит исключение не возникает…

И скорее всего просто где-то нужно передать какой-то параметр в модуль, чтобы он возвращал исключения
(Для это я и написал сюда, чтобы узнать кому и что передать)



0



2739 / 2342 / 620

Регистрация: 19.03.2012

Сообщений: 8,832

14.05.2017, 18:21

6

kak_ivan, raise возбуждает ошибку, с этим ни кто не спорит, но то, что ты делаешь называется дичь. Ты отлавливаешь ошибку и потом опять ее кидаешь дальше (причем кидаешь не правильно, нужно писать просто raise если хочешь кинуть ошибку дальше). То есть ты написал бесполезный обработчик ошибки, который НИКАК​ не влияет на ход исполнения программы.

Если хочешь увидеть​ ошибку в гуи, то создай message box и туда пиши ошибку.



0



0 / 0 / 1

Регистрация: 03.02.2015

Сообщений: 81

15.05.2017, 03:41

 [ТС]

7

Цитата
Сообщение от alex925
Посмотреть сообщение

Если хочешь увидеть​ ошибку в гуи, то создай message box и туда пиши ошибку.

Ну хоть что-то полезное сказал, спасибо)



0



2739 / 2342 / 620

Регистрация: 19.03.2012

Сообщений: 8,832

15.05.2017, 05:56

8

kak_ivan, я это сказал тебе ещё в самом начале.

Если было непонятно как вывести ошибку, надо было это переспросить и все.



0



0 / 0 / 1

Регистрация: 03.02.2015

Сообщений: 81

15.05.2017, 07:35

 [ТС]

9

Цитата
Сообщение от alex925
Посмотреть сообщение

Если было непонятно как вывести ошибку, надо было это переспросить


Переспрашиваю



0



alex925

2739 / 2342 / 620

Регистрация: 19.03.2012

Сообщений: 8,832

15.05.2017, 20:18

10

красивый способ

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import sys
 
from PyQt5 import QtWidgets
 
 
class MainWindow(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.setLayout(QtWidgets.QHBoxLayout())
 
        but = QtWidgets.QPushButton('Нажми меня')
        self.layout().addWidget(but)
        but.clicked.connect(self.error)
 
    def error(self):
        raise Exception('Неожиданная ошибкочка')
 
 
def my_excepthook(type, value, tback):
    QtWidgets.QMessageBox.critical(
        window, "CRITICAL ERROR", str(value),
        QtWidgets.QMessageBox.Cancel
    )
 
    sys.__excepthook__(type, value, tback)
 
 
sys.excepthook = my_excepthook
 
app = QtWidgets.QApplication([])
window = MainWindow()
window.show()
app.exec_()



2



kak_ivan

0 / 0 / 1

Регистрация: 03.02.2015

Сообщений: 81

16.05.2017, 06:56

 [ТС]

11

Цитата
Сообщение от alex925
Посмотреть сообщение

def error(self):
* * * * raise Exception(‘Неожиданная ошибкочка’)

Очень благодарен)
А как кинуть возникшую ошибку?

И как ее перехватить?
Например, на этом коде:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/usr/bin/python3
# -*- coding: utf-8 -*-
 
import sys
from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication
 
 
class Example(QMainWindow):
 
    def __init__(self):
        super().__init__()
 
        self.initUI()
 
 
    def initUI(self):
 
        btn1 = QPushButton("Button 1", self)
        btn1.move(30, 50)
 
        btn2 = QPushButton("Button 2", self)
        btn2.move(150, 50)
 
        btn1.clicked.connect(self.buttonClicked)
        btn2.clicked.connect(self.buttonClicked)
 
        self.statusBar()
 
        self.setGeometry(300, 300, 290, 150)
        self.setWindowTitle('Event sender')
        self.show()
 
 
    def buttonClicked(self):
 
        sender = self.sender()
        self.statusBar().showMessage(sender.text() + ' was pressed')
 
 
if __name__ == '__main__':
 
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())



0



5 ответов

Qt включает в себя класс диалога для сообщений об ошибках QErrorMessage который вы должны использовать, чтобы ваш диалог соответствовал системным стандартам. Чтобы показать диалог, просто создайте объект диалога, затем вызовите .showMessage(). Например:

error_dialog = QtWidgets.QErrorMessage()
error_dialog.showMessage('Oh no!')

Вот минимальный рабочий пример скрипта:

import PyQt5
from PyQt5 import QtWidgets

app = QtWidgets.QApplication([])

error_dialog = QtWidgets.QErrorMessage()
error_dialog.showMessage('Oh no!')

app.exec_()

mfitzp
24 окт. 2016, в 19:04

Поделиться

Все вышеперечисленные варианты не работали для меня, используя Komodo Edit 11.0. Просто вернул «1» или, если не был реализован «-1073741819».

Полезным для меня было: решение Ванлока.

def my_exception_hook(exctype, value, traceback):
    # Print the error and traceback
    print(exctype, value, traceback)
    # Call the normal Exception hook after
    sys._excepthook(exctype, value, traceback)
    sys.exit(1)

# Back up the reference to the exceptionhook
sys._excepthook = sys.excepthook

# Set the exception hook to our wrapping function
sys.excepthook = my_exception_hook

ZF007
13 нояб. 2017, в 20:15

Поделиться

Следующее должно работать:

msg = QMessageBox()
msg.setIcon(QMessageBox.Critical)
msg.setText("Error")
msg.setInformativeText(e)
msg.setWindowTitle("Error")

Это не тот же тип сообщения (разные GUI), но довольно близко. e — выражение для ошибки в python3

Надеюсь, что это помогло,

Narusan
24 окт. 2016, в 18:21

Поделиться

Не забудьте вызвать .exec() _ для отображения ошибки:

msg = QMessageBox()
msg.setIcon(QMessageBox.Critical)
msg.setText("Error")
msg.setInformativeText('More information')
msg.setWindowTitle("Error")
msg.exec_()

NShiell
08 янв. 2019, в 12:47

Поделиться

Чтобы показать окно сообщения, вы можете вызвать это определение:

from PyQt5.QtWidgets import QMessageBox

def clickMethod(self):
    QMessageBox.about(self, "Title", "Message")

Karam Qusai
17 апр. 2019, в 10:06

Поделиться

Ещё вопросы

  • 1Синхронизированный раздел внутри конструктора и различия синхронизированного конструктора
  • 1автоматический журнал исключений Java
  • 0Повторное открытие закрытого диалога переводит его в исходное положение после перемещения
  • 1Как поместить галерею в виджет на домашнем экране?
  • 0Сохранение ввода из предыдущей формы в новую форму
  • 1Где определены переменные метода exec ()?
  • 1Как мне зашифровать App.config для Azure WebJob?
  • 0Ошибка запроса данных PHP с объектом / строкой, теперь конструкция SQLite3
  • 1Почему метод OnStart () из ServiceBase имеет параметр arguments?
  • 0facebook: Как я могу получить ссылки на оригинальные фотографии из сообщений публичной группы
  • 0PHP SOAP-клиент несколько элементов
  • 0Почему динамическое поле выбора JSON не работает?
  • 1В Python добавление пустого списка в столбец dataframe с помощью лямбды повышает valueError
  • 0Как смешать две текстуры в OpenGL ES 1
  • 0MySQL положить в дубликаты идентификаторов
  • 0Передать переменные Java из активности Android в JavaScript в приложении phonegap
  • 0Как получить входное значение в beforeShowDays событии datequicker jquery?
  • 1Поместите Google Maps Maker x Расстояние с y Подшипником?
  • 0Пул MySQL в nodejs
  • 1Пространственные кнопки Image в Android
  • 1Android Webview — как захватить слово при нажатии?
  • 1ES6 super () в методах конструктора и прототипа
  • 0Следите за текущим значением ввода с обновлением на размытие
  • 0Дождитесь выполнения функции, пока новые данные не отобразятся в браузере
  • 1Как создать контроллер для веб-службы, которая использует другой API
  • 0Дайте приоритет второстепенному полю ORDER BY в MySQL
  • 0ngCordova: oauth с Google не работает
  • 0проверить функцию, которая возвращает тип треугольника
  • 0Директива не отображается на странице после изменения состояния, но после прямой загрузки
  • 1Формат в JSON с регулярным выражением
  • 0Не удается настроить среду разработки Android Cocos2d-x в Windows 7
  • 0SELECT * FROM table_name WHERE staus == открыто / ожидает / закрыто / все
  • 1Деинсталлировать пакеты невидимые в Android
  • 1Python + Requests + Eve: отправка данных для публикации завершается с ошибкой с кодом 422
  • 1Использование сканера и nextLine для завершения программы
  • 1Утечки памяти Java с классами
  • 1DOMDocument извлекает теги из встроенных скриптов PHP
  • 1Плагин для другого приложения для Android
  • 0текст netbeans не допускается при ошибке формы элемента
  • 1Как использовать Python и OpenCV для достижения определения кромки скважины, чтобы откалибровать некоторые мелочи
  • 1Asyncio против Asyncore для пользовательского сервера Python
  • 0AngularJS Количество Да / Нет Значения
  • 1Член PropertyChanged для INotifyPropertyChanged всегда равен нулю
  • 1Python — добавление строк между кадрами панды
  • 0Бэкэнд без состояния безопасен?
  • 1Android GPS-провайдер
  • 0Код для получения пользовательского ввода не выполняется / пропускается в C ++
  • 1Есть ли возможность конвертировать файл в формат .csv в Android?
  • 0Показать / скрыть DIV на основе выбранного переключателя
  • 0Почему @ связывает этот атрибут AngularJS, а = нет?

Dialogs are useful GUI components that allow you to communicate with the user (hence the name dialog). They are commonly used for file Open/Save, settings, preferences, or for functions that do not fit into the main UI of the application. They are small modal (or blocking) windows that sit in front of the main application until they are dismissed. Qt provides a number of ‘special’ built-in dialogs for the most common use-cases, allowing you to provide a platform-native user experience.

Standard GUI features — A search dialog
Standard GUI features — A search dialog

Standard GUI features — A file Open dialog
Standard GUI features — A file Open dialog

In Qt dialog boxes are handled by the QDialog class. To create a new dialog box simply create a new object of QDialog type passing in another widget, e.g. QMainWindow, as its parent.

Let’s create our own QDialog. We’ll start with a simple skeleton app with a button to press hooked up to a slot method.

python

import sys

from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton


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):
        print("click", s)


app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()

In the slot button_clicked (which receives the signal from the button press) we create the dialog instance, passing our QMainWindow instance as a parent. This will make the dialog a modal window of QMainWindow. This means the dialog will completely block interaction with the parent window.

python

import sys

from PyQt5.QtWidgets import QApplication, QDialog, QMainWindow, QPushButton


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):
        print("click", s)

        dlg = QDialog(self)
        dlg.setWindowTitle("HELLO!")
        dlg.exec()


app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()

Run it! Click the button and you’ll see an empty dialog appear.

Once we have created the dialog, we start it using .exec() — just like we did for QApplication to create the main event loop of our application. That’s not a coincidence: when you exec the QDialog an entirely new event loop — specific for the dialog — is created.

The QDialog completely blocks your application execution. Don’t start a dialog and expect anything else to happen anywhere else in your app. We’ll see later how you can use threads & processes to get you out of this pickle.

Our empty dialog overlaying the window.
Our empty dialog overlaying the window.

Like our very first window, this isn’t very interesting. Let’s fix that by adding a dialog title and a set of OK and Cancel buttons to allow the user to accept or reject the modal.

To customize the QDialog we can subclass it.

python

class CustomDialog(QDialog):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("HELLO!")

        QBtn = QDialogButtonBox.Ok | QDialogButtonBox.Cancel

        self.buttonBox = QDialogButtonBox(QBtn)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

        self.layout = QVBoxLayout()
        message = QLabel("Something happened, is that OK?")
        self.layout.addWidget(message)
        self.layout.addWidget(self.buttonBox)
        self.setLayout(self.layout)

In the above code, we first create our subclass of QDialog which we’ve called CustomDialog. As for the QMainWindow we apply our customizations in the class __init__ block so our customizations are applied as the object is created. First we set a title for the QDialog using .setWindowTitle(), exactly the same as we did for our main window.

The next block of code is concerned with creating and displaying the dialog buttons. This is probably a bit more involved than you were expecting. However, this is due to Qt’s flexibility in handling dialog button positioning on different platforms.

You could of course choose to ignore this and use a standard QButton in a layout, but the approach outlined here ensures that your dialog respects the host desktop standards (OK on left vs. right for example). Messing around with these behaviors can be incredibly annoying to your users, so I wouldn’t recommend it.

The first step in creating a dialog button box is to define the buttons want to show, using namespace attributes from QDialogButtonBox. The full list of buttons available is below.

  • QDialogButtonBox.Ok
  • QDialogButtonBox.Open
  • QDialogButtonBox.Save
  • QDialogButtonBox.Cancel
  • QDialogButtonBox.Close
  • QDialogButtonBox.Discard
  • QDialogButtonBox.Apply
  • QDialogButtonBox.Reset
  • QDialogButtonBox.RestoreDefaults
  • QDialogButtonBox.Help
  • QDialogButtonBox.SaveAll
  • QDialogButtonBox.Yes
  • QDialogButtonBox.YesToAll
  • QDialogButtonBox.No
  • QDialogButtonBox.Abort
  • QDialogButtonBox.Retry
  • QDialogButtonBox.Ignore
  • QDialogButtonBox.NoButton

These should be sufficient to create any dialog box you can think of. You can construct a line of multiple buttons by OR-ing them together using a pipe (|). Qt will handle the order automatically, according to platform standards. For example, to show an OK and a Cancel button we used:

python

buttons = QDialogButtonBox.Ok | QDialogButtonBox.Cancel

The variable buttons now contains an integer value representing those two buttons. Next, we must create the QDialogButtonBox instance to hold the buttons. The flag for the buttons to display is passed in as the first parameter.

To make the buttons have any effect, you must connect the correct QDialogButtonBox signals to the slots on the dialog. In our case we’ve connected the .accepted and .rejected signals from the QDialogButtonBox to the handlers for .accept() and .reject() on our subclass of QDialog.

Lastly, to make the QDialogButtonBox appear in our dialog box we must add it to the dialog layout. So, as for the main window we create a layout, and add our QDialogButtonBox to it (QDialogButtonBox is a widget), and then set that layout on our dialog.

Finally, we launch the CustomDialog in our MainWindow.button_clicked slot.

python

class MainWindow(QMainWindow):

    # ... add the following method after the __init__

    def button_clicked(self, s):
        print("click", s)

        dlg = CustomDialog()
        if dlg.exec():
            print("Success!")
        else:
            print("Cancel!")

Run it! Click to launch the dialog and you will see a dialog box with buttons.

Our dialog with a label and buttons.
Our dialog with a label and buttons.

When you click the button to launch the dialog, you may notice that it appears away from the parent window — probably in the center of the screen. Normally you want dialogs to appear over their launching window to make them easier for users to find. To do this we need to give Qt a parent for the dialog. If we pass our main window as the parent, Qt will position the new dialog so that the center of the dialog aligns with the center of the window.

We can modify our CustomDialog class to accept a parent parameter.

python

class CustomDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.setWindowTitle("HELLO!")

        QBtn = QDialogButtonBox.Ok | QDialogButtonBox.Cancel

        self.buttonBox = QDialogButtonBox(QBtn)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

        self.layout = QVBoxLayout()
        message = QLabel("Something happened, is that OK?")
        self.layout.addWidget(message)
        self.layout.addWidget(self.buttonBox)
        self.setLayout(self.layout)

We set a default value of parent=None so we can omit the parent if we wish.

Then, when we create our instance of CustomDialog we can pass the main window in as a parameter. In our button_clicked method, self is our main window object.

python

    def button_clicked(self, s):
        print("click", s)

        dlg = CustomDialog(self)
        if dlg.exec():
            print("Success!")
        else:
            print("Cancel!")

Run it! Click to launch the dialog and you should see the dialog pop up right in the middle of the parent window.

Our dialog, centered over the parent window.
Our dialog, centered over the parent window.

Congratulations! You’ve created your first dialog box. Of course, you can continue to add any other content to the dialog box that you like. Simply insert it into the layout as normal.

Simple message dialogs with QMessageBox

There are many dialogs which follow the simple pattern we just saw — a message with buttons with which you can accept or cancel the dialog. While you can construct these dialogs yourself, Qt also provides a built-in message dialog class called QMessageBox. This can be used to create information, warning, about or question dialogs.

The example below creates a simple QMessageBox and shows it.

python

import sys

from PyQt5.QtWidgets import QApplication, QDialog, QMainWindow, QMessageBox, QPushButton


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(self)
        dlg.setWindowTitle("I have a question!")
        dlg.setText("This is a simple dialog")
        button = dlg.exec()

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

app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()

Run it! You’ll see a simple dialog with an OK button.

A QMessageBox dialog.
A QMessageBox dialog.

As with the dialog button box we looked at already, the buttons shown on a QMessageBox are also configured with the same set of constants which can be combined with | (the binary OR operator) to show multiple buttons. The full list of available button types is shown below.

  • QMessageBox.Ok
  • QMessageBox.Open
  • QMessageBox.Save
  • QMessageBox.Cancel
  • QMessageBox.Close
  • QMessageBox.Discard
  • QMessageBox.Apply
  • QMessageBox.Reset
  • QMessageBox.RestoreDefaults
  • QMessageBox.Help
  • QMessageBox.SaveAll
  • QMessageBox.Yes
  • QMessageBox.YesToAll
  • QMessageBox.No
  • QMessageBox.NoToAll
  • QMessageBox.Abort
  • QMessageBox.Retry
  • QMessageBox.Ignore
  • QMessageBox.NoButton

You can also tweak the icon shown on the dialog by setting the icon with one of the following.

Icon state Description
QMessageBox.NoIcon The message box does not have an icon.
QMessageBox.Question The message is asking a question.
QMessageBox.Information The message is informational only.
QMessageBox.Warning The message is warning.
QMessageBox.Critical The message indicates a critical problem.

For example, the following creates a question dialog with Yes and No buttons.

python

    def button_clicked(self, s):
        dlg = QMessageBox(self)
        dlg.setWindowTitle("I have a question!")
        dlg.setText("This is a question dialog")
        dlg.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
        dlg.setIcon(QMessageBox.Question)
        button = dlg.exec()

        if button == QMessageBox.Yes:
            print("Yes!")
        else:
            print("No!")

Run it! You’ll see a question dialog with Yes and No buttons.

Question dialog created using QMessageBox.
Question dialog created using QMessageBox.

Over 10,000 developers have bought Create GUI Applications with Python & Qt!

[[ discount.discount_pc ]]% OFF for
the next [[ discount.duration ]]
[[discount.description ]]
with the code [[ discount.coupon_code ]]

Purchasing Power Parity

Developers in [[ country ]] get [[ discount.discount_pc ]]% OFF on all books & courses
with code [[ discount.coupon_code ]]

Built in QMessageBox dialogs

To make things even simpler the QMessageBox has a number of methods which can be used to construct these types of message dialog. These methods are shown below —

python

QMessageBox.about(parent, title, message)
QMessageBox.critical(parent, title, message)
QMessageBox.information(parent, title, message)
QMessageBox.question(parent, title, message)
QMessageBox.warning(parent, title, message)

The parent parameter is the window which the dialog will be a child of. If you’re launching your dialog from your main window, you can just pass in self.
The following example creates a question dialog, as before, with Yes and No buttons.

python

    def button_clicked(self, s):

        button = QMessageBox.question(self, "Question dialog", "The longer message")

        if button == QMessageBox.Yes:
            print("Yes!")
        else:
            print("No!")

Run it! You’ll see the same result, this time using the built in .question() method.

The built-in question dialog.
The built-in question dialog.

Notice that rather than call exec() we now simply call the dialog method and the dialog is created. The return value of each of the methods is the button which was pressed. We can detect what has been pressed by comparing the return value to the button constants.

The four information, question, warning and critical methods also accept optional buttons and defaultButton arguments which can be used to tweak the buttons shown on the dialog and select one by default. Generally though you don’t want to change this from the default.

python

    def button_clicked(self, s):

        button = QMessageBox.critical(
            self,
            "Oh dear!",
            "Something went very wrong.",
            buttons=QMessageBox.Discard | QMessageBox.NoToAll | QMessageBox.Ignore,
            defaultButton=QMessageBox.Discard,
        )

        if button == QMessageBox.Discard:
            print("Discard!")
        elif button == QMessageBox.NoToAll:
            print("No to all!")
        else:
            print("Ignore!")

Run it! You’ll see a critical dialog with customized buttons.

Critical error! This is a terrible dialog.
Critical error! This is a terrible dialog.

For most situations these simple dialogs are all you need.

Понравилась статья? Поделить с друзьями:

Читайте также:

  • Вывих скулы как исправить
  • Вывих проявляется найдите ошибочный ответ
  • Вывих нижней челюсти как исправить
  • Вывих лопатки симптомы как исправить
  • Вывих запястья как исправить

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии