PyQt window closes after opening
<p>I have two files, namely <em>main.py</em> and <em>client_window.py</em>. I want to show the client window after the progress bar completes its progress. But I find that the client window opens and closes immediately. Can someone suggest how to change the code, so that I'll grasp the correct logic?</p>

<p>This is <em>main.py</em>:</p>

<pre><code>"""
This module defines the User Interface
"""

import sys
import time

from cloudL.ui import client_window

from PyQt4 import QtGui

from PyQt4 import QtCore
from PyQt4.QtGui import *


class ProgressBarWidget(QtGui.QDialog):

    def __init__(self, parent=None):
        super(ProgressBarWidget, self).__init__(parent)
        layout = QtGui.QVBoxLayout(self)

        self.label = QLabel()
        self.tryAgain = QPushButton("Try Again")
        self.progressBar = QtGui.QProgressBar(self)
        self.progressBar.setRange(0,100)
        self.tryAgain.setEnabled(False)

        layout.addWidget(self.label)
        layout.addWidget(self.progressBar)
        layout.addWidget(self.tryAgain)

        self.myLongTask = TaskThread()
        self.myLongTask.notifyProgress.connect(self.onProgress)
        self.myLongTask.start()

    def onStart(self):
        self.tryAgain.setEnabled(False)
        self.myLongTask.start()
        self.label.setText("")

    def onProgress(self, i):
        self.progressBar.setValue(i)
        if(self.progressBar.value() == 100):
            #app = QApplication(sys.argv)
            #global ex
            ex = client_window.main()
            ex.show()
            #ex.main()
            #ex.show()
            #sys.exit(app.exec_())
        else:
            self.tryAgain.setEnabled(True)
            self.tryAgain.clicked.connect(self.onStart)
            self.label.setText("Cannot connect to Server! Please Try Again!")


class TaskThread(QtCore.QThread):
    notifyProgress = QtCore.pyqtSignal(int)
    def run(self):
        for i in range(101):
            self.notifyProgress.emit(i)
            time.sleep(0.005)

class MainWindow(QWidget):
    """
    This window will be the first screen to appear
    """

    def __init__(self, parent = None):
        super(MainWindow, self).__init__(parent)
        """
        Initializes parameters required by the MainWindow
        """
        self.option = ""       # to specify the if the selected option is Server or Client
        self.ex = None

    def main(self):
        """
        This function is the origin where the initiation of the control takes place
        :return: Returns nothing
        """

        mainLayout = QVBoxLayout()
        mainLayout.setAlignment(QtCore.Qt.AlignCenter)

        radioLayout = QHBoxLayout()
        mainLayout.setAlignment(QtCore.Qt.AlignCenter)

        label = QLabel()
        label.setText("Select whether to act as a Server or a Client")
        labelFont = QFont()
        labelFont.setBold(True)
        labelFont.setPointSize(15)
        label.setFont(labelFont)

        mainLayout.addWidget(label)
        mainLayout.addStretch()

        b1 = QRadioButton("Server")
        b1.setChecked(True)
        b1.toggled.connect(lambda : btnstate(b1))
        radioLayout.addWidget(b1)

        b2 = QRadioButton("Client")
        b2.toggled.connect(lambda : btnstate(b2))
        radioLayout.addWidget(b2)

        self.option = ""

        def btnstate(b):
            """
            Nested function to define the action when radio button is toggled
            :param b: Button which is toggled currently
            :return: Returns nothing
            """
            if b.text() == "Server" and b.isChecked() == True:
                self.option = "Server"

            if b.text() == "Client" and b.isChecked() == True:
                self.option = "Client"

        start = QPushButton("Start")

        mainLayout.addLayout(radioLayout)
        mainLayout.addStretch()
        mainLayout.addWidget(start)

        self.setLayout(mainLayout)
        self.setGeometry(400, 200, 300, 300)
        self.setWindowTitle("CloudL")

        start.clicked.connect(self.showdialog)

    def showdialog(self):
        """
        A sample message box to check and display which option is chosen
        :return: Returns nothing
        """
        #app = QApplication(sys.argv)
        self.ex = ProgressBarWidget(self)
        self.ex.setGeometry(400, 200, 500, 150)
        self.destroy()
        self.ex.setWindowTitle("CloudL")
        self.ex.show()


"""
Execute the required action
"""
app = QApplication(sys.argv)
ex = MainWindow()
ex.main()
ex.show()
sys.exit(app.exec_())
</code></pre>

<p>And <em>client_window.py</em> is as follows:</p>

<pre><code>#client_window.py

import sys
from PyQt4 import QtCore

from PyQt4.QtGui import *
from PyQt4.QtCore import *

class myListWidget(QListWidget):
    def Clicked(self, item):
        QMessageBox.information(self, "ListWidget", "You clicked: " + item.text())


class Example(QWidget):
    def __init__(self):
        super(Example, self).__init__()
        self.listWidget = None
        self.initUI()

    def initUI(self):
        hbox = QHBoxLayout(self)

        topleftLayout = QVBoxLayout()
        topleftLayout.setAlignment(QtCore.Qt.AlignTop)
        topleft = QFrame()
        topleft.setFrameShape(QFrame.StyledPanel)
        label = QLabel()
        label.setText("SERVER LIST")
        label.setAlignment(QtCore.Qt.AlignCenter)
        topleftLayout.addWidget(label)
        self.addServerList(topleftLayout)
        topleft.setLayout(topleftLayout)
        bottom = QFrame()
        bottom.setFrameShape(QFrame.StyledPanel)

        splitter1 = QSplitter(Qt.Horizontal)
        textedit = QTextEdit()
        splitter1.addWidget(topleft)
        splitter1.addWidget(textedit)
        splitter1.setSizes([100, 200])

        splitter2 = QSplitter(Qt.Vertical)
        splitter2.addWidget(splitter1)
        splitter2.addWidget(bottom)
        splitter2.setSizes([225, 100])

        hbox.addWidget(splitter2)

        self.setLayout(hbox)
        QApplication.setStyle(QStyleFactory.create('Cleanlooks'))

        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('QSplitter demo')
        self.showMaximized()

    def addServerList(self, layout):
        self.listWidget = myListWidget()
        self.listWidget.resize(300, 120)

        self.listWidget.addItem("Item 1");
        self.listWidget.addItem("Item 2");
        self.listWidget.addItem("Item 3");
        self.listWidget.addItem("Item 4");

        self.listWidget.setWindowTitle('PyQT QListwidget Demo')
        self.listWidget.itemClicked.connect(self.listWidget.Clicked)
        layout.addWidget(self.listWidget)


def main():
    ex = Example()
    ex.showMaximized()
    return ex


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main()
    sys.exit(app.exec_())
</code></pre>

<p>I'm making the call to <code>client_window</code> at:</p>

<pre><code>def onProgress(self, i):
    self.progressBar.setValue(i)
    if(self.progressBar.value() == 100):
        #app = QApplication(sys.argv)
        #global ex
        ex = client_window.main()
        ex.show()
        #ex.main()
        #ex.show()
        #sys.exit(app.exec_())
    else:
        self.tryAgain.setEnabled(True)
        self.tryAgain.clicked.connect(self.onStart)
        self.label.setText("Cannot connect to Server! Please Try Again!")
</code></pre>

<p>Also, if I include the lines <code>app = QApplication(sys.argv)</code> and <code>sys.exit(app.exec_())</code> in the client window I'm getting the following error:</p>

<blockquote>
  <p>QCoreApplication::exec: The event loop is already running pyqt error</p>
</blockquote>

<p>You need to keep a reference to the client window, otherwise it will be garbage-collected as soon as <code>onProgress</code> returns:</p>

<pre><code>def onProgress(self, i):
    self.progressBar.setValue(i)
    if self.progressBar.value() == 100:
        self.client_window = client_window.main()
    else:
        self.tryAgain.setEnabled(True)
        self.tryAgain.clicked.connect(self.onStart)
        self.label.setText("Cannot connect to Server! Please Try Again!")
</code></pre>

python qt python-3.x pyqt pyqt4