I have designed Main window & subwindow in PYQT5 designer When I run the code the controls move upwards in the subwindow But when the subwindow is maximized the controls look correctly spaced from top of window Also when I resize the subwindow manually the window is not painted correctly but the same is ok when I use Maximize & restore buttons
I want to place objects in subwindow at absolute postion relative the top of sub window
Subwindow Class
# -*- coding: utf-8 -*-
# DataForm implementation generated from reading ui file 'subDataForm.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QGridLayout, QWidget, QDesktopWidget, QMdiArea, QMdiSubWindow
class Ui_DataForm(object):
def setupUi(self, DataForm):
DataForm.setObjectName("DataForm")
DataForm.resize(577, 366)
DataForm.setStyleSheet("")
self.label_2 = QtWidgets.QLabel(DataForm)
self.label_2.setGeometry(QtCore.QRect(10, 79, 56, 23))
self.label_2.setObjectName("label_2")
self.lcdNumber = QtWidgets.QLCDNumber(DataForm)
self.lcdNumber.setGeometry(QtCore.QRect(10, 50, 64, 23))
self.lcdNumber.setObjectName("lcdNumber")
self.pushButton = QtWidgets.QPushButton(DataForm)
self.pushButton.setGeometry(QtCore.QRect(10, 294, 75, 23))
self.pushButton.setStyleSheet("")
self.pushButton.setObjectName("pushButton")
self.label = QtWidgets.QLabel(DataForm)
self.label.setGeometry(QtCore.QRect(10, 187, 47, 16))
self.label.setObjectName("label")
self.lineEdit = QtWidgets.QLineEdit(DataForm)
self.lineEdit.setGeometry(QtCore.QRect(10, 268, 133, 20))
self.lineEdit.setObjectName("lineEdit")
self.comboBox = QtWidgets.QComboBox(DataForm)
self.comboBox.setGeometry(QtCore.QRect(10, 242, 69, 20))
self.comboBox.setObjectName("comboBox")
self.retranslateUi(DataForm)
QtCore.QMetaObject.connectSlotsByName(DataForm)
def retranslateUi(self, DataForm):
_translate = QtCore.QCoreApplication.translate
DataForm.setWindowTitle(_translate("DataForm", "DataForm"))
self.label_2.setText(_translate("DataForm", "TextLabel"))
self.pushButton.setText(_translate("DataForm", "PushButton"))
self.label.setText(_translate("DataForm", "TextLabel"))
Mainwindow Class
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'mainform.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QGridLayout, QWidget, QDesktopWidget, QMdiArea, QMdiSubWindow
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("E:/tools9/rajsoft.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
MainWindow.setWindowIcon(icon)
#self.centralwidget = QtWidgets.QWidget(MainWindow)
self.mdi = QMdiArea()
self.centralwidget = QtWidgets.QWidget(self.mdi)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
self.mdiArea = QtWidgets.QMdiArea(self.centralwidget)
self.mdiArea.setObjectName("mdiArea")
self.verticalLayout.addWidget(self.mdiArea)
self.gridLayout.addLayout(self.verticalLayout, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
self.menubar.setObjectName("menubar")
self.menuMain_Menu = QtWidgets.QMenu(self.menubar)
self.menuMain_Menu.setObjectName("menuMain_Menu")
MainWindow.setMenuBar(self.menubar)
self.toolBar = QtWidgets.QToolBar(MainWindow)
self.toolBar.setObjectName("toolBar")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
self.actionNew_Window = QtWidgets.QAction(MainWindow)
self.actionNew_Window.setObjectName("actionNew_Window")
self.actionExit = QtWidgets.QAction(MainWindow)
self.actionExit.setObjectName("actionExit")
self.menuMain_Menu.addAction(self.actionNew_Window)
self.menuMain_Menu.addAction(self.actionExit)
self.menubar.addAction(self.menuMain_Menu.menuAction())
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.menuMain_Menu.setTitle(_translate("MainWindow", "Main Menu"))
self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
self.actionNew_Window.setText(_translate("MainWindow", "New Window"))
self.actionExit.setText(_translate("MainWindow", "Exit"))
Main Program
import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from mainform import Ui_MainWindow
from subform import Ui_DataForm
from data_toolbar import Ui_FormToolBar
from PyQt5.QtWidgets import QGridLayout, QWidget, QDesktopWidget
from PyQt5.QtWidgets import QGridLayout, QWidget, QDesktopWidget, QMdiArea, QMdiSubWindow
class SubForm(QMdiSubWindow):
def __init__(self):
super().__init__()
self.subform = Ui_DataForm()
self.subform.setupUi(self)
self.tb = Ui_FormToolBar("data_print","n")
self.tb.setupUi(self)
self.resizeEvent = self.resized
self.resize(700, 600)
def resized(self,event):
self.tb.reconfig(self)
class AppWindow(QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
colors = QAction('Colors', self)
exitAct = QAction('Exit', self)
exitAct.triggered.connect(self.close_application)
btnTB = QToolButton()
btnTB.setText("TEST")
self.ui.toolBar.addAction(colors)
self.ui.toolBar.addAction(exitAct)
self.ui.toolBar.addWidget(btnTB)
self.ui.actionExit.triggered.connect(self.close_application)
self.ui.actionNew_Window.triggered.connect(self.new_window)
#center the window
qtRectangle = self.frameGeometry()
centerPoint = QDesktopWidget().availableGeometry().center()
qtRectangle.moveCenter(centerPoint)
sub = SubForm()
self.ui.mdiArea.addSubWindow(sub)
self.ui.statusbar.showMessage("HI THERE")
#sub.move(qtRectangle.topLeft())
#center the window
sub.show()
def close_application(self):
print("whooaaaa so custom!!!")
sys.exit()
def new_window(self):
sub = SubForm()
self.ui.mdiArea.addSubWindow(sub)
sub.show()
app = QApplication(sys.argv)
w = AppWindow()
w.setWindowState(Qt.WindowMaximized)
w.show()
sys.exit(app.exec_())
Data Toobar
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_FormToolBar(object):
def __init__(self,toolbar_type,button_type):
super().__init__()
self.toolbar_type = toolbar_type
self.toolbar_type = self.toolbar_type.lower()
self.button_type = button_type
self.button_type = self.button_type.lower()
self.next_left = 0
if (self.button_type == "" or self.button_type == "n"):
self.buttonheight = 41
self.buttonwidht = 60
if (self.button_type == "i"):
self.buttonheight = 29
self.buttonwidht = 30
def setupUi(self, FormToolBar):
_translate = QtCore.QCoreApplication.translate
FormToolBar.setObjectName("FormToolBar")
FormToolBar.resize(730, 55)
self.frame = QtWidgets.QFrame(FormToolBar)
self.frame.setGeometry(QtCore.QRect(0, 0, 721, 51))
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
FormToolBar.setWindowTitle(_translate("FormToolBar", "Form"))
self.nextleft = 0
if (self.toolbar_type == 'data' or self.toolbar_type == 'data_print' or self.toolbar_type == 'data_nav' or self.toolbar_type == 'data_nav_print' ):
self.btn_New = QtWidgets.QToolButton(self.frame)
self.btn_New.setGeometry(QtCore.QRect(self.nextleft, 0, self.buttonwidht, self.buttonheight))
icon3 = QtGui.QIcon()
icon3.addPixmap(QtGui.QPixmap("D:/tools9/NEW.BMP"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btn_New.setIcon(icon3)
if (self.button_type !="i"):
self.btn_New.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
self.btn_New.setObjectName("btn_New")
self.btn_New.setText(_translate("FormToolBar", "New"))
self.nextleft = self.nextleft + self.buttonwidht
self.btn_Find = QtWidgets.QToolButton(self.frame)
self.btn_Find.setGeometry(QtCore.QRect(self.nextleft, 0, self.buttonwidht, self.buttonheight))
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("D:/tools9/find.bmp"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btn_Find.setIcon(icon)
if (self.button_type !="i"):
self.btn_Find.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
self.btn_Find.setObjectName("btn_Find")
self.btn_Find.setText(_translate("FormToolBar", "Find"))
self.nextleft = self.nextleft + self.buttonwidht + 2
if (self.toolbar_type == 'data' or self.toolbar_type == 'data_print' )!= True:
self.btn_First = QtWidgets.QToolButton(self.frame)
self.btn_First.setGeometry(QtCore.QRect(self.nextleft, 0, self.buttonwidht, self.buttonheight))
icon4 = QtGui.QIcon()
icon4.addPixmap(QtGui.QPixmap("D:/tools9/Ffc/Graphics/TOP.BMP"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btn_First.setIcon(icon4)
if (self.button_type !="i"):
self.btn_First.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
self.btn_First.setObjectName("btn_First")
self.btn_First.setText(_translate("FormToolBar", "First"))
self.nextleft = self.nextleft + self.buttonwidht
self.btn_Prev = QtWidgets.QToolButton(self.frame)
self.btn_Prev.setGeometry(QtCore.QRect(self.nextleft, 0, self.buttonwidht, self.buttonheight))
icon7 = QtGui.QIcon()
icon7.addPixmap(QtGui.QPixmap("D:/tools9/Ffc/Graphics/PREVIOUS.BMP"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btn_Prev.setIcon(icon7)
if (self.button_type !="i"):
self.btn_Prev.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
self.btn_Prev.setObjectName("btn_Prev")
self.btn_Prev.setText(_translate("FormToolBar", "Previous"))
self.nextleft = self.nextleft + self.buttonwidht
self.btn_Next = QtWidgets.QToolButton(self.frame)
self.btn_Next.setGeometry(QtCore.QRect(self.nextleft, 0, self.buttonwidht, self.buttonheight))
icon5 = QtGui.QIcon()
icon5.addPixmap(QtGui.QPixmap("D:/tools9/Ffc/Graphics/next.bmp"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btn_Next.setIcon(icon5)
if (self.button_type !="i"):
self.btn_Next.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
self.btn_Next.setObjectName("btn_Next")
self.btn_Next.setText(_translate("FormToolBar", "Next"))
self.nextleft = self.nextleft + self.buttonwidht
self.btn_Last = QtWidgets.QToolButton(self.frame)
self.btn_Last.setGeometry(QtCore.QRect(self.nextleft, 0, self.buttonwidht, self.buttonheight))
icon10 = QtGui.QIcon()
icon10.addPixmap(QtGui.QPixmap("D:/tools9/Ffc/Graphics/BOTTOM.BMP"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btn_Last.setIcon(icon10)
if (self.button_type !="i"):
self.btn_Last.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
self.btn_Last.setText(_translate("FormToolBar", "Last"))
self.btn_Last.setObjectName("btn_Last")
self.nextleft = self.nextleft + self.buttonwidht + 2
if (self.toolbar_type == 'data' or self.toolbar_type == 'data_print' or self.toolbar_type == 'data_nav' or self.toolbar_type == 'data_nav_print'):
self.btn_Modify = QtWidgets.QToolButton(self.frame)
self.btn_Modify.setGeometry(QtCore.QRect(self.nextleft, 0, self.buttonwidht, self.buttonheight))
icon9 = QtGui.QIcon()
icon9.addPixmap(QtGui.QPixmap("D:/tools9/OPEN.BMP"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btn_Modify.setIcon(icon9)
if (self.button_type !="i"):
self.btn_Modify.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
self.btn_Modify.setObjectName("btn_Modify")
self.btn_Modify.setText(_translate("FormToolBar", "Modify"))
self.nextleft = self.nextleft + self.buttonwidht
self.btn_Delete = QtWidgets.QToolButton(self.frame)
self.btn_Delete.setGeometry(QtCore.QRect(self.nextleft, 0, self.buttonwidht, self.buttonheight))
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap("D:/tools9/CUT.BMP"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btn_Delete.setIcon(icon1)
if (self.button_type !="i"):
self.btn_Delete.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
self.btn_Delete.setObjectName("btn_Delete")
self.btn_Delete.setText(_translate("FormToolBar", "Delete"))
self.nextleft = self.nextleft + self.buttonwidht
self.btn_Save = QtWidgets.QToolButton(self.frame)
self.btn_Save.setGeometry(QtCore.QRect(self.nextleft, 0, self.buttonwidht, self.buttonheight))
icon11 = QtGui.QIcon()
icon11.addPixmap(QtGui.QPixmap("D:/tools9/SAVE.BMP"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btn_Save.setIcon(icon11)
if (self.button_type !="i"):
self.btn_Save.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
self.btn_Save.setObjectName("btn_Save")
self.btn_Save.setText(_translate("FormToolBar", "Save"))
self.nextleft = self.nextleft + self.buttonwidht
self.btn_Cancel = QtWidgets.QToolButton(self.frame)
self.btn_Cancel.setGeometry(QtCore.QRect(self.nextleft, 0, self.buttonwidht, self.buttonheight))
icon8 = QtGui.QIcon()
icon8.addPixmap(QtGui.QPixmap("D:/tools9/UNDO.BMP"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btn_Cancel.setIcon(icon8)
if (self.button_type !="i"):
self.btn_Cancel.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
self.btn_Cancel.setObjectName("btn_Cancel")
self.btn_Cancel.setText(_translate("FormToolBar", "Cancel"))
self.nextleft = self.nextleft + self.buttonwidht
if (self.toolbar_type == 'data_print' or self.toolbar_type == 'data_nav_print' or self.toolbar_type == 'nav_print'):
self.btn_Print = QtWidgets.QToolButton(self.frame)
self.btn_Print.setGeometry(QtCore.QRect(self.nextleft, 0, self.buttonwidht, self.buttonheight))
icon6 = QtGui.QIcon()
icon6.addPixmap(QtGui.QPixmap("D:/tools9/PRINT.BMP"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btn_Print.setIcon(icon6)
if (self.button_type !="i"):
self.btn_Print.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
self.btn_Print.setObjectName("btn_Print")
self.btn_Print.setText(_translate("FormToolBar", "Print"))
self.nextleft = self.nextleft + self.buttonwidht
self.btn_Exit = QtWidgets.QToolButton(self.frame)
self.btn_Exit.setGeometry(QtCore.QRect(self.nextleft, 0, self.buttonwidht, self.buttonheight))
icon2 = QtGui.QIcon()
icon2.addPixmap(QtGui.QPixmap("D:/tools9/CLOSE.BMP"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btn_Exit.setIcon(icon2)
if (self.button_type !="i"):
self.btn_Exit.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
self.btn_Exit.setObjectName("btn_Exit")
self.btn_Exit.setText(_translate("FormToolBar", "Exit"))
self.nextleft = self.nextleft + self.buttonwidht
QtCore.QMetaObject.connectSlotsByName(FormToolBar)
FormToolBar.setTabOrder(self.btn_New, self.btn_Find)
if (self.toolbar_type == 'data' or self.toolbar_type == 'data_print' )!= True:
FormToolBar.setTabOrder(self.btn_Find, self.btn_First)
FormToolBar.setTabOrder(self.btn_First, self.btn_Prev)
FormToolBar.setTabOrder(self.btn_Prev, self.btn_Next)
FormToolBar.setTabOrder(self.btn_Next, self.btn_Last)
FormToolBar.setTabOrder(self.btn_Last, self.btn_Modify)
if (self.toolbar_type == 'data' or self.toolbar_type == 'data_print' ):
FormToolBar.setTabOrder(self.btn_Find, self.btn_Modify)
FormToolBar.setTabOrder(self.btn_Modify, self.btn_Delete)
FormToolBar.setTabOrder(self.btn_Delete, self.btn_Save)
FormToolBar.setTabOrder(self.btn_Save, self.btn_Cancel)
else:
FormToolBar.setTabOrder(self.btn_Last, self.btn_Modify)
FormToolBar.setTabOrder(self.btn_Modify, self.btn_Delete)
FormToolBar.setTabOrder(self.btn_Delete, self.btn_Save)
FormToolBar.setTabOrder(self.btn_Save, self.btn_Cancel)
if (self.toolbar_type == 'data_print' or self.toolbar_type == 'data_nav_print' or self.toolbar_type == 'nav_print' ):
FormToolBar.setTabOrder(self.btn_Cancel, self.btn_Print)
FormToolBar.setTabOrder(self.btn_Print, self.btn_Exit)
else:
FormToolBar.setTabOrder(self.btn_Cancel, self.btn_Exit)
FormToolBar.resize(self.nextleft + 10, 55)
self.frame.setGeometry(QtCore.QRect(0, 0, self.nextleft + 8, 54))
def reconfig(self,parent):
self.po = parent
parentwidth = parent.frameGeometry().width()
parentheight = parent.frameGeometry().height()
mywidth = self.frame.frameGeometry().width()
myheight = self.frame.frameGeometry().height()
width = ((parentwidth/2) - (mywidth/2))
height = parentheight- (myheight + 30)
self.frame.move(width,height)
self.btn_Exit.clicked.connect(sys.exit)
self.frame.update()
Your issue happens because you are setting an absolute position based on the window geometry, which can also include the title bar; in your case the vertical position will always be window.y() + titlebar.height() + y
, so if the window is maximized the titlebar will have no height, thus showing the "correct" position you wanted.
The correct implementation of a QMdiSubWindow is to use setWidget()
to add its contents. It's almost like using setCentralWidget()
for a QMainWindow.
class SubForm(QMdiSubWindow):
def __init__(self):
super().__init__()
# create the widget and set its ui
self.subform = QWidget()
subform_ui = Ui_DataForm()
subform_ui.setupUi(self.subform)
# set the widget for the window
self.setWidget(self.subform)
# you should *not* do this!!!
self.tb = Ui_FormToolBar("data_print","n")
self.tb.setupUi(self)
About the last lines, you should never call setupUi more than once on the same widget, and not even against an object that has a class different from what it expects: in your case, Ui_FormToolBar should be a QWidget, but you're using with a QMdiSubWindow instead; while it seems to work, you might face some serious problems in the future. What you should do is to create a separate QWidget and use the form setupUi with it.
Finally, I strongly suggest you to not edit the python files generated by pyuic
to create your programs; read the official documentation on how to correctly use the files created with Designer instead.