How to insert a Form inside mainWindow

徘徊边缘 提交于 2020-06-28 14:22:07

问题


I'd like to display a Form into a mainWindow tab. The mainWindow is already created and filled with empty tabs, and the Form is also created and filled with empty comboBox, labels and such.

The mainWindow is called home and the Form listInvoice. They work well on their own, but when I call listInvoice from the home tab, it opens a new window displaying the listInvoice GUI instead of displaying listInvoice within the tab.

Do you know how to call a form from within a mainWindow tab? Thank you for your help.

home.ui file (created by QT Designer):

<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>500</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="QLabel" name="lDate">
      <property name="text">
       <string>TextLabel</string>
      </property>
     </widget>
    </item>
    <item row="1" column="0">
     <widget class="QTabWidget" name="tabWidget">
      <property name="tabPosition">
       <enum>QTabWidget::West</enum>
      </property>
      <property name="currentIndex">
       <number>0</number>
      </property>
      <property name="elideMode">
       <enum>Qt::ElideNone</enum>
      </property>
      <widget class="QWidget" name="tabHome">
       <attribute name="title">
        <string>Home</string>
       </attribute>
       <layout class="QGridLayout" name="gridLayout_2"/>
      </widget>
      <widget class="QWidget" name="tabCompanies">
       <attribute name="title">
        <string>Companies</string>
       </attribute>
      </widget>
      <widget class="QWidget" name="tabProjects">
       <attribute name="title">
        <string>Projects</string>
       </attribute>
      </widget>
      <widget class="QWidget" name="tabInvoices">
       <attribute name="title">
        <string>Invoices</string>
       </attribute>
      </widget>
     </widget>
    </item>
   </layout>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

The Home class:

# Class import
from listInvoice import ListInvoice

# GUI manager 
from PyQt5.QtWidgets import QApplication, QComboBox, QDialog, QDialogButtonBox, QFrame, QLabel, QLineEdit, QMainWindow, QMessageBox, QPushButton, QTabWidget, QVBoxLayout,QWidget
from PyQt5.uic import loadUi

# Other imports
import datetime
import sys


class Home(QMainWindow):
    print("home.py")
    def __init__(self):
        super(Home, self).__init__()
        loadUi("home.ui", self)
        self.setWindowTitle("Home")

        # Display current date
        self.lDate.setText(str(datetime.date.today()))

        # Insert widget into tabs
        self.tabInvoices = ListInvoice()


app = QApplication(sys.argv)
widget = Home()
widget.show()
sys.exit(app.exec_())

The listInvoice.ui (created by QT Designer):

<?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>735</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <layout class="QGridLayout" name="gridLayout">
   <item row="1" 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="1" column="2">
    <widget class="QPushButton" name="pbSearch">
     <property name="text">
      <string>Search</string>
     </property>
    </widget>
   </item>
   <item row="4" column="0" colspan="3">
    <spacer name="verticalSpacer">
     <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="0" column="2">
    <widget class="QPushButton" name="pbAddInvoice">
     <property name="text">
      <string>Add invoice</string>
     </property>
    </widget>
   </item>
   <item row="2" column="0">
    <widget class="QLabel" name="label">
     <property name="text">
      <string>Filter by:</string>
     </property>
    </widget>
   </item>
   <item row="1" column="1">
    <widget class="QLineEdit" name="leSearch"/>
   </item>
   <item row="2" column="1" colspan="2">
    <widget class="QPushButton" name="pbCertified">
     <property name="text">
      <string>To certified</string>
     </property>
     <property name="checkable">
      <bool>true</bool>
     </property>
    </widget>
   </item>
   <item row="3" column="0" colspan="3">
    <widget class="QTableWidget" name="twInvoices"/>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>

And the ListInvoice class:

class ListInvoice(QDialog):
    print("listInvoice.py")
    def __init__(self):
        super(ListInvoice, self).__init__()
        loadUi("listInvoice.ui", self)
        self.setWindowTitle("Invoices")

The expected output should be the listInvoice within the home tab.


回答1:


You are wrong to think that by doing sef.tabInvoices = ListInvoice() you are replacing the widget, then no, the variable self.tabInvoices points the object and when you reassign it then that variable will no longer point to the initial object but to another.

Considering the above there are at least 2 solutions:

1. Use a Layout:

Use a layout to place the ListInvoice widget inside the tabInvoices, it is not being replaced but placing inside.

class Home(QMainWindow):
    print("home.py")
    def __init__(self):
        super(Home, self).__init__()
        loadUi("home.ui", self)
        self.setWindowTitle("Home")
        # Display current date
        self.lDate.setText(str(datetime.date.today()))
        # Insert widget into tabs
        self.tabInvoices_w = ListInvoice()  # <---
        lay = QVBoxLayout(self.tabInvoices) # <---
        lay.addWidget(self.tabInvoices_w)   # <---

2. Promote widget

Promote ListInvoice using Qt Designer, for more information you can review the following answers:

  • https://stackoverflow.com/a/47273625
  • https://stackoverflow.com/a/46671439
  • https://stackoverflow.com/a/53504994
  • https://stackoverflow.com/a/53545128
  • https://stackoverflow.com/a/53926554

Considering that the solution is to change the home.ui to:

<?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>800</width>
    <height>500</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="QLabel" name="lDate">
      <property name="text">
       <string>TextLabel</string>
      </property>
     </widget>
    </item>
    <item row="1" column="0">
     <widget class="QTabWidget" name="tabWidget">
      <property name="tabPosition">
       <enum>QTabWidget::West</enum>
      </property>
      <property name="currentIndex">
       <number>3</number>
      </property>
      <property name="elideMode">
       <enum>Qt::ElideNone</enum>
      </property>
      <widget class="QWidget" name="tabHome">
       <attribute name="title">
        <string>Home</string>
       </attribute>
       <layout class="QGridLayout" name="gridLayout_2"/>
      </widget>
      <widget class="QWidget" name="tabCompanies">
       <attribute name="title">
        <string>Companies</string>
       </attribute>
      </widget>
      <widget class="QWidget" name="tabProjects">
       <attribute name="title">
        <string>Projects</string>
       </attribute>
      </widget>
      <widget class="ListInvoice" name="tabInvoices">
       <attribute name="title">
        <string>Invoices</string>
       </attribute>
      </widget>
     </widget>
    </item>
   </layout>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <customwidgets>
  <customwidget>
   <class>ListInvoice</class>
   <extends>QWidget</extends>
   <header>listInvoice</header>
   <container>1</container>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

And remove self.tabInvoices = ListInvoice() in home class since it is not necessary.



来源:https://stackoverflow.com/questions/56941021/how-to-insert-a-form-inside-mainwindow

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!