8

I've been trying to close a QDialog window that is branching off of my main window. The following have not worked for me so far:

self.close()
QDialog.close()

I tried other commands such as exit and exec_() with no luck. The most common error I get is

[className] object has no attribute 'close'

# Creating our window
class Ui_MainWindow(object):

    # Sets up GUI
    def setupUi(self, MainWindow):

        [GUI CODE]      

    # Sets text for parts of GUI
    def retranslateUi(self, MainWindow):

        [MORE GUI CODE]

    # Function handling screencap on click and metadata for filenames
    def cap_on_Click(arg1,arg2):

        popup = QDialog()
        popup_ui = Ui_Dialog()
        popup_ui.setupUi(popup)
        popup.show()
        sys.exit(popup.exec_())

The above is my main window

class Ui_Dialog(object):

    def setupUi(self, Dialog):

        [GUI CODE]

    def retranslateUi(self, Dialog):

        [MORE GUI CODE]

    def button_click(self, arg1):

        self.close()

The second block is the dialog window code. How do I close this dialog window?

C Snyder
  • 81
  • 1
  • 1
  • 4

4 Answers4

7

First of all, sorry for the links related to C++, but Python has the same concept.

You can try using the reject or accept or done function to close the dialog box. By doing this, you're setting the return value appropriately (Rejected, Accepted or the one you specify as the argument).

All in all, you should try calling YourDialog.done(n) to close the dialog and return n and YourDialog.accept() or YourDialog.reject() when you want it accepted/rejected.

ForceBru
  • 43,482
  • 10
  • 63
  • 98
  • I've tried analogs like that, but for some reason my dialog isn't defined there. – C Snyder Jul 01 '15 at 13:32
  • 1
    @CSnyder, it isn't defined _where_? – ForceBru Jul 01 '15 at 14:28
  • In the Ui_Dialog class, which is where i try to call the self.close() function. – C Snyder Jul 01 '15 at 17:38
  • 2
    @CSnyder, have you tried calling `self.done()` or something like this? – ForceBru Jul 02 '15 at 16:47
  • I've tried every command meant to close windows that I could find, and none of them worked. I switched over to C++ rather than continue with python. C++ has no such issues that I've run into. – C Snyder Jul 06 '15 at 14:16
  • 1
    @CSnyder: how are you supposed to call `close()` on `Ui_Dialog` if it inherits from `object`? The code generated with Qt Designer should stay unmodified. What you do is you have to use multiple inheritance and make your dialog inherit both from `QDialog` and (untampered with) `Ui_Dialog`. Then you have access both to what was generated and what ships with `QDialog` – z33k Jan 07 '19 at 15:11
  • @z33k Exactly z33k – hiperbolt Apr 23 '19 at 20:00
4

I guess the problem is that Ui_Dialog does not inherit QDialog, so reject(), accept() and done() is not defined. I think

class Ui_Dialog(object):

should be changed to

class Ui_Dialog(QDialog):

But I can not test it because minimal working example is not provided.

cges30901
  • 470
  • 3
  • 10
  • i got this right. but in my case, still it doesn't work using dialog.close() nor dialog.done().the window still open – greendino Jun 24 '20 at 11:15
  • Please provide minimal, reproducible example. – cges30901 Jun 25 '20 at 12:31
  • Chances are that `Ui_Dialog` is automatically generated through pyuic or similar. You shouldn't manually edit that file. I found a good practise to just create a custom class that inherits the `QWidget` / `QDialog` (or analog) **and** `Ui_Dialog` – Buzz May 24 '22 at 14:03
3

Since a QDialog is a QWidget, and a QWidget has the close() method, I don't understand how it can not work. You should never invoke popup.exec_() though, since it will happily require a lot of your code to be reentrant without you realizing it. It is unnecessary - you already have the application event loop running and on the call stack when cap_on_Click is executing.

After popup.show(), the dialog will be visible and usable until it gets accepted or rejected by the user. Hopefully your design for the dialog connects the button box's accepted() and rejected() signals to the dialog's accept() and reject() slots. That is the default behavior of a QDialog template provided with Qt Creator and perhaps Qt Designer as well, but you should check it by going into the signal/slot editor mode while viewing the Ui file.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
2

I know it's over 5months but I choose to drop this comment here, it might be of help to others tomorrow. To be able to close or cancel an opened dialog box, using only self.close would close the entire program. use this example:

self.dlg = QDialog(self)
self.dlg.setWindowTitle("Admin")
self.dlg.setGeometry(100,100,300,200)
btnBox = QDialogButtonBox()
btnBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)

btnBox.rejected.connect(self.close1)
def close1():
    self.dlg.close()
Flair
  • 2,609
  • 1
  • 29
  • 41
CCCC
  • 241
  • 2
  • 10