问题
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