Search code examples
pythonpyqt5qt-designerqmainwindowqstackedwidget

Adding windows to a QStackedWidget in Qt designer doesn't work as expected


I am currently working on a project that involves developing a GUI, that I can send emails to someone and if I need I should be able to save it on a database. The GUI has two pages, the senders credentials are entered in first page and the email is sent using second page. I made UI for first and second pages using Qt designer. And I made a UI (MainWindow) containing a stacked widget, so that I can stack the page1 and page2 in it.

I choose to do it this way because I want to switch from pages anytime I want and the attributes related to page1 and page2 are supposed to be used at the same time.(I need to access them using one class, that is MainApp class). But when I try to stack page1 and page2 to the stackedWidget it doesn't give an error, but it doesn't load the pages also. Can someone point out what I am doing wrong here?

from PyQt5 import uic
from PyQt5 import QtCore, QtWidgets, QtGui
import sys
import os

class MainApp(QtWidgets.QMainWindow):
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        uic.loadUi('designs/win_stacked.ui', self)
        self.win_1 = win1()
        self.win_2 = win2()
        self.stackedWidget.addWidget(self.win_1)
        print('why stacked widget is not loaded with other windows??')
        self.stackedWidget.addWidget(self.win_2)
        
class win1(QtWidgets.QMainWindow):
    def __init__(self):
        super(win1, self).__init__()
        uic.loadUi('designs/win1.ui', self)
        
class win2(QtWidgets.QMainWindow):
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        uic.loadUi('designs/win2.ui', self)

        
if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    wind = MainApp()
    wind.show()
    sys.exit(app.exec_())

(Link to all the UI files: https://drive.google.com/drive/folders/1UC8TVCsmwaQfksd6MtPf-9tGXxtOpH45?usp=sharing).


Solution

  • The problem is largely caused by using a QMainWindow for the pages in the stacked-widget. These pages should just be a plain QWidget instead. There are also a few issues with the layouts. I have fixed all these issues in the solution shown below, and also added a button-handler to show how to switch pages. Hopefully this should help get you started. To test things properly, please make sure you use all the files provided below:

    screenshot

    import sys, os
    from PyQt5 import uic
    from PyQt5 import QtCore, QtWidgets, QtGui
    
    class MainApp(QtWidgets.QMainWindow):
        def __init__(self):
            super().__init__()
            uic.loadUi('designs/win_stacked.ui', self)
            self.win_1 = win1()
            self.win_2 = win2()
            self.stackedWidget.addWidget(self.win_1)
            self.stackedWidget.addWidget(self.win_2)
            self.stackedWidget.setCurrentWidget(self.win_2)
            self.win_2.butPrevious.clicked.connect(
                lambda: self.stackedWidget.setCurrentWidget(self.win_1))
    
    class win1(QtWidgets.QWidget):
        def __init__(self):
            super().__init__()
            uic.loadUi('designs/win1.ui', self)
    
    class win2(QtWidgets.QWidget):
        def __init__(self):
            super().__init__()
            uic.loadUi('designs/win2.ui', self)
    
    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
        wind = MainApp()
        wind.show()
        sys.exit(app.exec_())
    

    win_stacked.ui:

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>MainWindow</class>
     <widget class="QMainWindow" name="MainWindow">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>578</width>
        <height>373</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>MainWindow</string>
      </property>
      <widget class="QWidget" name="centralwidget">
       <layout class="QGridLayout" name="gridLayout">
        <item row="0" column="0">
         <widget class="QStackedWidget" name="stackedWidget"/>
        </item>
       </layout>
      </widget>
      <widget class="QMenuBar" name="menubar">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>578</width>
         <height>24</height>
        </rect>
       </property>
      </widget>
      <widget class="QStatusBar" name="statusbar"/>
     </widget>
     <resources/>
     <connections/>
    </ui>
    

    win1.ui:

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>Form</class>
     <widget class="QWidget" name="Form">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>579</width>
        <height>474</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>Form</string>
      </property>
      <layout class="QVBoxLayout" name="verticalLayout">
       <item>
        <layout class="QGridLayout" name="gridLayout" columnstretch="0,1,0">
         <item row="2" column="0">
          <widget class="QLabel" name="label_2">
           <property name="text">
            <string>Username</string>
           </property>
          </widget>
         </item>
         <item row="4" column="1">
          <widget class="QPushButton" name="butSetup">
           <property name="text">
            <string>Setup</string>
           </property>
          </widget>
         </item>
         <item row="4" column="0">
          <spacer name="horizontalSpacer">
           <property name="orientation">
            <enum>Qt::Horizontal</enum>
           </property>
           <property name="sizeHint" stdset="0">
            <size>
             <width>40</width>
             <height>20</height>
            </size>
           </property>
          </spacer>
         </item>
         <item row="3" column="0">
          <widget class="QLabel" name="label_3">
           <property name="text">
            <string>Password</string>
           </property>
          </widget>
         </item>
         <item row="4" column="2">
          <spacer name="horizontalSpacer_2">
           <property name="orientation">
            <enum>Qt::Horizontal</enum>
           </property>
           <property name="sizeHint" stdset="0">
            <size>
             <width>40</width>
             <height>20</height>
            </size>
           </property>
          </spacer>
         </item>
         <item row="1" column="0">
          <spacer name="verticalSpacer_2">
           <property name="orientation">
            <enum>Qt::Vertical</enum>
           </property>
           <property name="sizeHint" stdset="0">
            <size>
             <width>20</width>
             <height>40</height>
            </size>
           </property>
          </spacer>
         </item>
         <item row="2" column="1" colspan="2">
          <widget class="QTextEdit" name="textUsername">
           <property name="sizePolicy">
            <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
             <horstretch>0</horstretch>
             <verstretch>0</verstretch>
            </sizepolicy>
           </property>
          </widget>
         </item>
         <item row="3" column="1" colspan="2">
          <widget class="QTextEdit" name="textPassword">
           <property name="sizePolicy">
            <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
             <horstretch>0</horstretch>
             <verstretch>0</verstretch>
            </sizepolicy>
           </property>
          </widget>
         </item>
         <item row="0" column="1">
          <widget class="QLabel" name="label">
           <property name="font">
            <font>
             <pointsize>16</pointsize>
            </font>
           </property>
           <property name="text">
            <string>Here you gotta input your own or sender email address username and password</string>
           </property>
           <property name="wordWrap">
            <bool>true</bool>
           </property>
          </widget>
         </item>
        </layout>
       </item>
      </layout>
     </widget>
     <resources/>
     <connections/>
    </ui>
    

    win2.ui:

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>Form</class>
     <widget class="QWidget" name="Form">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>505</width>
        <height>441</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>Form</string>
      </property>
      <layout class="QVBoxLayout" name="verticalLayout">
       <item>
        <layout class="QGridLayout" name="gridLayout_2">
         <item row="0" column="0">
          <widget class="QLabel" name="label">
           <property name="text">
            <string>Receiver's Email</string>
           </property>
          </widget>
         </item>
         <item row="0" column="1">
          <widget class="QTextEdit" name="textEdit"/>
         </item>
         <item row="1" column="0">
          <widget class="QLabel" name="label_4">
           <property name="text">
            <string>Subject</string>
           </property>
          </widget>
         </item>
         <item row="1" column="1">
          <widget class="QTextEdit" name="textEdit_2"/>
         </item>
         <item row="2" column="0">
          <widget class="QLabel" name="label_2">
           <property name="text">
            <string>Body</string>
           </property>
          </widget>
         </item>
         <item row="2" column="1">
          <widget class="QTextEdit" name="textEdit_3"/>
         </item>
        </layout>
       </item>
       <item>
        <layout class="QGridLayout" name="gridLayout">
         <item row="0" column="0">
          <spacer name="horizontalSpacer">
           <property name="orientation">
            <enum>Qt::Horizontal</enum>
           </property>
           <property name="sizeHint" stdset="0">
            <size>
             <width>142</width>
             <height>20</height>
            </size>
           </property>
          </spacer>
         </item>
         <item row="0" column="1">
          <widget class="QPushButton" name="butAttachments">
           <property name="text">
            <string>Add Attachments</string>
           </property>
          </widget>
         </item>
         <item row="0" column="2">
          <spacer name="horizontalSpacer_2">
           <property name="orientation">
            <enum>Qt::Horizontal</enum>
           </property>
           <property name="sizeHint" stdset="0">
            <size>
             <width>185</width>
             <height>20</height>
            </size>
           </property>
          </spacer>
         </item>
         <item row="1" column="0">
          <widget class="QPushButton" name="butSend">
           <property name="text">
            <string>Send</string>
           </property>
          </widget>
         </item>
         <item row="1" column="2">
          <widget class="QPushButton" name="butUpload">
           <property name="text">
            <string>Upload to DB</string>
           </property>
          </widget>
         </item>
         <item row="2" column="1">
          <widget class="QLabel" name="lblSendError">
           <property name="text">
            <string/>
           </property>
          </widget>
         </item>
         <item row="2" column="2">
          <widget class="QLabel" name="lblUploadError">
           <property name="text">
            <string/>
           </property>
          </widget>
         </item>
         <item row="3" column="0" colspan="3">
          <widget class="QPushButton" name="butPrevious">
           <property name="text">
            <string>Add new sender data</string>
           </property>
          </widget>
         </item>
        </layout>
       </item>
      </layout>
     </widget>
     <resources/>
     <connections/>
    </ui>