App without main window - with many widgets showing one by one



  • I would like to have app without main window, but with many widgets showing one by one (dialogs won't work for me).

    I have following code:
    @# -- coding: utf-8 --
    from PyQt4 import QtCore, QtGui

    from start_window import Ui_Form
    from second_window import Ui_Form as Ui_Form_Second

    class StartForm(QtGui.QWidget):
    def init(self, parent=None):
    QtGui.QWidget.init(self, parent)
    self.ui = Ui_Form()
    self.ui.setupUi(self)
    self.ui.pushButton.clicked.connect(self.button)

    def button(self):
        secondWindow = SecondForm()
        secondWindow.show()
        self.hide()
    

    class SecondForm(QtGui.QWidget):
    def init(self, parent=None):
    QtGui.QWidget.init(self, parent)
    self.ui = Ui_Form_Second()
    self.ui.setupUi(self)

    if name == "main":
    app = QtGui.QApplication(sys.argv)
    myapp = StartForm()
    myapp.show()
    sys.exit(app.exec_())@

    When I press button app closes. How to pass execution of the app to the second widget? I am not interested in using QWizard and QStackedWidget.


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Then you have to either open the next widget before closing the last (because by default closing the "main" widget will end the application) or disable application ending on last widget closed and re-enable it when appropriate.

    Just curiosity, why doesn't any of the current Qt technology fit in your design ?



  • Hi
    The problem with your current logic is that, you are saving the reference of "secondForm" in "secondWindow" which is a local variable and destroyed when execution of "button" function is completed. You have to put the reference of "secondForm" in "self.secondWindow", everything else is fine.



  • As Qurban says your problem is that you're "secondWindow" is going out of scope. What you're basically trying to do is create a managed stack of parentless windows (i.e. a QStackWidget without the actual widget). The following is a simplistic example that uses a subclass if QApplication to manage both the widgets and the transitions between them:

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

    class Window(QWidget):
    next=pyqtSignal()
    prev=pyqtSignal()

    def __init__(self, title, **kwargs):
        QWidget.__init__(self, **kwargs)
    
        self.resize(320,240)
        self.setWindowTitle(title)
        l=QVBoxLayout(self)
        l.addWidget(QPushButton("Prev", self, clicked=self.prev))
        l.addWidget(QPushButton("Next", self, clicked=self.next))
    

    class Application(QApplication):
    def init(self, *args, **kwargs):
    QApplication.init(self, *args, **kwargs)

        self._index=None
        self._windows=[Window(t, next=self.next, prev=self.prev) for t in ["Window 1", "Window 2", "Window 3"]]
        self.next()
    
    @pyqtSlot()
    def prev(self):
        if self._index in (None, 0): return
    
        self._windows[self._index].hide()
        self._index-=1
        self._windows[self._index].show()
        self._windows[self._index].raise_()
    
    @pyqtSlot()
    def next(self):
        if self._index>=(len(self._windows)-1): return
        if self._index is not None:
            self._windows[self._index].hide()
            self._index+=1
        else: self._index=0
    
        self._windows[self._index].show()
        self._windows[self._index].raise_()
    

    if name=="main":
    from sys import argv, exit

    a=Application(argv)
    exit(a.exec_())
    

    @

    Hope this helps ;o)



  • Thank you guys for your answers!

    I solved this by adding two lines (for sure it works, but is it OK?:):

    @# -- coding: utf-8 --
    from PyQt4 import QtCore, QtGui
    from start_window import Ui_Form
    from second_window import Ui_Form as Ui_Form_Second

    class StartForm(QtGui.QWidget):
    def init(self, parent=None):
    QtGui.QWidget.init(self, parent)
    self.ui = Ui_Form()
    self.ui.setupUi(self)
    self.child_windows = None # this one
    self.ui.pushButton.clicked.connect(self.button)

    def button(self):
        secondWindow = SecondForm()
        secondWindow.show()
        self.child_windows = secondWindow # this one
        self.hide()
    

    class SecondForm(QtGui.QWidget):
    def init(self, parent=None):
    QtGui.QWidget.init(self, parent)
    self.ui = Ui_Form_Second()
    self.ui.setupUi(self)

    if name == "main":
    app = QtGui.QApplication(sys.argv)
    myapp = StartForm()
    myapp.show()
    sys.exit(app.exec_())@

    I am just wondering if this approach doesn't leave any garbages in memory, like closed forms?

    I ma not using QWizard because this is going to be something more than widget with "Next" and "Previous" buttons. Nor QStackedWidget since, at some point, I want to have more than one visible widget at a time.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.