pythonpyqtqmessagebox

QMessageBox with "Dont show this message again" in python


I'm developing a UI using PyQt 5. I'm using stackedWidget to alternate between screens. Every time I open a screen I show a pop up message (QMessageBox), but I want to able to the user to define if he/she wants to see the pop up next time that he/she goes back to the screen. I've tried this solution, but as I am using a method to show the pop up message the solution described in the hyperlink is not working. I developed a MVCE to help.

MainWindow.py:

import sys
from PyQt5.QtWidgets import QApplication, QMessageBox, QCheckBox
from PyQt5.QtWidgets import QMainWindow
from Ui_MainWindow import Ui_MainWindow
class MainWindow:
    def __init__(self):
        self.main_win = QMainWindow()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self.main_win)
        self.ui.stackedWidget.setCurrentWidget(self.ui.page)
        self.ui.pushButton.clicked.connect(self.show1)
        self.ui.pushButton_2.clicked.connect(self.show2)
    def popupInfo(self, msg1, msg2):
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Information)
        cb = QCheckBox()
        cb.setText("Don't show this again")
        msg.setCheckBox(cb)
        msg.setText(msg1)
        msg.setInformativeText(msg2)
        msg.setWindowTitle("Warning")
        msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
        retval = msg.exec_()
    def show(self):
        self.main_win.show()
    def show1(self):
        self.ui.stackedWidget.setCurrentWidget(self.ui.page)
        self.popupInfo("aaa","bbb")
    def show2(self):
        self.ui.stackedWidget.setCurrentWidget(self.ui.page_2)
        self.popupInfo("aaa", "bbb")
if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_win = MainWindow()
    main_win.show()
    sys.exit(app.exec_())

Ui_MainWindow.py:

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(664, 522)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(120, 470, 75, 23))
        self.pushButton.setObjectName("pushButton")
        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_2.setGeometry(QtCore.QRect(390, 470, 75, 23))
        self.pushButton_2.setObjectName("pushButton_2")
        self.stackedWidget = QtWidgets.QStackedWidget(self.centralwidget)
        self.stackedWidget.setGeometry(QtCore.QRect(20, 20, 581, 421))
        self.stackedWidget.setObjectName("stackedWidget")
        self.page = QtWidgets.QWidget()
        self.page.setObjectName("page")
        self.stackedWidget.addWidget(self.page)
        self.page_2 = QtWidgets.QWidget()
        self.page_2.setObjectName("page_2")
        self.stackedWidget.addWidget(self.page_2)
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "Screen 1"))
        self.pushButton_2.setText(_translate("MainWindow", "Screen 2"))

The window diagram

enter image description here

Iteration 1 - Window 'i' is showed and the pop up is showed and the checkbox is marked by the user.

Iteration 2 - The user goes to window j, the pop up is showed but the check box is not marked.

Iteration 3 - The user goes to window k, the pop up is show and the checkbox is marked by the user.

Iteration 4 - The user goes back to window i, the pop up is not showed because he marked the checkbox on iteration 1.

Iteration 5 - The user goes back to window k because he marked the checkbox on iteration 3.

Iteration 6 - The user goes to window j again, now he marks the checkbox when the pop up is showed.

Iteration 7 - The user goes back to window i, the pop up is not showed because he marked the checkbox on iteration 1.

Iteration 8 - The user goes back to window j and the pop up is not showed because on iteration 6 he marked the checkbox.

Iteration 9 - The user goes to window k and the pop up is not showed because he marked the check box on iteration 3.


Solution

  • You need to store the checkbox state somewhere, you can't expect that it "magically" works.

    Create an empty list, change the popupInfo function by adding an argument for the changed page, then if the page is in the list, don't show the popup; otherwise add the page if the checkbox is checked and, depending on your needs, if the message box is accepted (your example wasn't really clear, so we don't really know what is the actual purpose of the message box).

    class MainWindow:
        def __init__(self):
            # ...
            self.ignorePopups = []
    
        def popupInfo(self, page, msg1, msg2):
            if page in self.ignorePopups:
                return
            # ...
            retval = msg.exec_()
            if retval and cb.isChecked():
                self.ignorePopups.append(page)
    
        def show1(self):
            self.ui.stackedWidget.setCurrentWidget(self.ui.page)
            self.popupInfo(self.ui.page, "aaa", "bbb")
    
        def show2(self):
            self.ui.stackedWidget.setCurrentWidget(self.ui.page_2)
            self.popupInfo(self.ui.page_2, "aaa", "bbb")
    

    For future reference, please try to be more clear in your posts, answer everything that is requested, avoid unnecessary and repeated comments, and avoid vague statements such as "is not working": a phrase like that, without any further explanation about what doesn't work, doesn't really mean anything to us, and it requires annoying comments to wait for clarifications you should have provided in the first place.