-1

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.

Mutante
  • 278
  • 5
  • 18
  • 1
    Your question is confusing, let's say you have N windows and you go from window "i" to window "j" so a popup will open by default, now my question is if the user presses the QCheckBox and goes to the window "k" different from the window "i", then should it be shown in the popup? That is, when the user presses the checkbox, it should not only be shown when it returns to "i" but when it goes to other windows or it should no longer never show up. – eyllanesc May 20 '21 at 23:44
  • You are correct. Let's say that we have 2 windows, i and j . The user starts the application on screen 'i' and marks the checkbox, then he goes to screen 'j', the popup will show again. Let's say that he not marked the checkbox on screen 'j' and goes back to screen 'i'. The popup should not appear on screen 'i' (because he marked the checkbox) and when he returns to screen 'j' the pop up will show again because he not marked the checkbox. – Mutante May 21 '21 at 00:04
  • 1
    Your explanation is confusing, let's say there are 3 windows: "1", "2" and "3". If the application starts in window "1" then should the popup be displayed? And if I check the popup checkbox and go to window 2 then the popup should be shown? If instead I go back to window 1 then should it show? Your question is unclear so I recommend you make a diagram that explains the desired behavior – eyllanesc May 21 '21 at 00:11
  • Yes, you are correct. But when you go back to window 1 the popup should not be showed. I'll try to make a diagram in paint. – Mutante May 21 '21 at 00:15
  • 1
    @Mutante Correct me if I'm wrong, but if I understand it correctly, the popup should be shown everytime a "new" page is shown, no matter what the previous was, right? In any case, what do you mean with "the solution described in the hyperlink is not working"? – musicamante May 21 '21 at 00:16
  • @musicamante I'm drawing a diagram, just a moment, – Mutante May 21 '21 at 00:22
  • @eyllanesc I've update the question with the diagram – Mutante May 21 '21 at 00:39
  • @Mutante so, it's just as I said, a popup is always shown everytime a new page is shown, *unless* the last time the user checked the checkbox for that, and in that case no popup is shown the *next* time that page is opened. You didn't answer the question, though. – musicamante May 21 '21 at 00:44
  • @musicamante Yes, you are correct. – Mutante May 21 '21 at 00:46
  • Please, for the last time, answer the question. What is "not working"?!? – musicamante May 21 '21 at 00:49
  • @musicamante As I used the `popupInfo` function to show the popup, i couldn't adapt the last 4 lines of the other solution that i posted on hyperlink. I tried to put that code into my code, but didn't worked (Even when I mark the checkbox, the popup still appears when I go back to a screen) – Mutante May 21 '21 at 00:52

1 Answers1

1

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.

musicamante
  • 41,230
  • 6
  • 33
  • 58