On Saturday, August 26, 2017 at 11:11:55 AM UTC-7, Konstantin Krayn wrote:
>
> I am a newcomer to Qt too, and I had exactly the same issue with 
> Windows+Python+Qt+Spider while trying to run the same zetcode tutorial 
> example. I have no idea why it does not work as intended but replacing the 
> handler in question QCoreApplication.instance().quit with self.close 
> appears to work. I came up with this workaround after observing that the 
> standard way to close the app window by clicking "x" button in the window 
> title bar works as expected, and I assume that self.close() does something 
> like that.
>
> Still would be helpful to understand why quit() does not work as one would 
> expect and what is the right way to quit this application in Spyder 
> environment.
>
>         qbtn.clicked.connect(QCoreApplication.instance().quit)
>>
>>


Hello Konstantin,

Thank you for your observation that self.close() is a reasonable 
work-around. I had the same thought as you and found that it worked, too. 
But I wasn't satisfied without some sort of explanation, so I continued 
searching the web during the last week and I found the following 
information related to the order of garbage collection that might point to 
the root of this issue. However, I still have no idea why the code behaves 
differently in the Spyder enviroment vs. from the command line:
http://pyqt.sourceforge.net/Docs/PyQt5/gotchas.html#crashes-on-exit

After implementing the structural change per the sourceforge description, 
here's what my code looks like, and it works properly both from the Spyder 
environment as well as from the command line:

#########################
import sys
from PyQt5.QtWidgets import QWidget, QPushButton, QApplication
from PyQt5.QtCore import QCoreApplication


class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):

        qbtn = QPushButton('Quit', self)
        qbtn.clicked.connect(QCoreApplication.instance().quit)
#        qbtn.clicked.connect(self.close)
        qbtn.resize(qbtn.sizeHint())
        qbtn.move(50, 50)

        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('Quit button')
        self.show()


def main():
    """
    SOURCE:
    http://pyqt.sourceforge.net/Docs/PyQt5/gotchas.html#crashes-on-exit

    Creating the "main" function to contain the event loop and call the GUI
    Example class changes the garbage collection order (module destructors 
vs.
    the actual Qapplication destruction). This keeps the GUI from hanging
    and killing the kernel. Note the location of "ex.show()"
    """
    global app

    # The "if app is None" logic below keeps kernal from dying every other 
time.
    # 
https://stackoverflow.com/questions/40094086/python-kernel-dies-for-second-run-of-pyqt5-gui
    # Qt does not like more than one QApplication object in the same 
process.
    # The "instance()" code gets the application instance if it was already
    # created.
    app = QCoreApplication.instance()
    if app is None:
        app = QApplication(sys.argv) # QApp requires the sys arg list.

    ex = Example()
    ex.show() # Widget first created in memory; "show()" required for 
display.

    app.exec()


if __name__ == "__main__":
    main()

#################################

I'm not sure as to why "app" has to be set as a global in main(). It 
appears to work OK with this line commented out...

Since I don't understand, I've just left the "global app" line as-is, and 
for every subsequent PyQt5 tutorial I have been using this same main() and 
show(), et. al., code structure with great success.


Incidentally, how far along in the zetcode tutorials are you? Were you able 
to get the "View StatusBar" checkMenu's QAction to work properly? I was 
thinking about posting this as another, separate 
Windows+Python3+PyQt5+Spyder issue... 

Here are my symptoms: Running the checkMenu code in Spyder, the toggle 
doesn't permanently change the statusBar view on/off as I believe is 
intended. The statusBar message turns off permanently just by hovering the 
mouse cursor over the View menu label. Then, the only way to get the 
statusBar message to be visible again is to click the checkMenu "View" 
button and hover the mouse over the text in the QAction sub-menu. 
Alternatively, when I run this same code from the command line, the 
checkMenu QAction to toggle whether the StatusBar is visible or not 
actually terminates the application instead. 

Let me know when you get to this point in the tutorial or what you 
experienced if you've already tried it out...

Jim


 

-- 
You received this message because you are subscribed to the Google Groups 
"spyder" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/spyderlib.
For more options, visit https://groups.google.com/d/optout.

Reply via email to