Как закрепить подокно в области MDI в pyqt5 с помощью qtDesigner

Я пытаюсь создать подокно в области MDI в pyqt5, используя файл .ui для моего главного окна. Когда я запускаю действие для отображения подокна, оно отображается как отдельное окно (не закрепленное в области MDI, как предполагалось). Я попытался добавить подокно с помощью этого руководства (codeloop.org MDI Area Tutorial), и он работает нормально, но я не смог воспроизвести его, загрузив файл .ui.

app.py

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

scriptPath = os.path.dirname(os.path.realpath(__file__))
uiFile = scriptPath + '\\' + 'mainwindow.ui'

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)
        self.initUI()
    def initUI(self):
        #load the UI page
        self.ui_main = uic.loadUi(uiFile, self)
        self.action1.triggered.connect(lambda: self.fileBarTrig('test'))
    def fileBarTrig(self,p):
        print(p)
        self.subwindow.show()
        self.mdiArea.tileSubWindows()

def main():
    app = QtWidgets.QApplication(sys.argv)
    main = MainWindow()
    main.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="windowModality">
   <enum>Qt::NonModal</enum>
  </property>
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QVBoxLayout" name="verticalLayout">
    <item alignment="Qt::AlignLeft">
     <widget class="QMdiArea" name="mdiArea">
      <property name="activationOrder">
       <enum>QMdiArea::CreationOrder</enum>
      </property>
      <property name="viewMode">
       <enum>QMdiArea::SubWindowView</enum>
      </property>
      <property name="documentMode">
       <bool>false</bool>
      </property>
      <widget class="QWidget" name="subwindow">
       <property name="windowTitle">
        <string>subwindow</string>
       </property>
       <widget class="QPushButton" name="pushButton">
        <property name="geometry">
         <rect>
          <x>70</x>
          <y>80</y>
          <width>75</width>
          <height>23</height>
         </rect>
        </property>
        <property name="text">
         <string>help</string>
        </property>
       </widget>
      </widget>
      <widget class="QWidget" name="subwindow_2">
       <property name="windowTitle">
        <string>Subwindow</string>
       </property>
      </widget>
     </widget>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>21</height>
    </rect>
   </property>
   <widget class="QMenu" name="menuFile">
    <property name="title">
     <string>File</string>
    </property>
    <addaction name="action1"/>
   </widget>
   <addaction name="menuFile"/>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
  <action name="action1">
   <property name="text">
    <string>1</string>
   </property>
  </action>
 </widget>
 <resources/>
 <connections/>
</ui>

app.py работает с незакрепленным подокном


person tmorgan497    schedule 09.06.2020    source источник


Ответы (1)


Кажется, это ошибка или, по крайней мере, недостаток мощности, из-за которой виджеты не вставляются в QMdiArea, что можно увидеть, если проанализировать код, сгенерированный pyuic5.

Таким образом, решение состоит в том, чтобы добавить виджеты в QMdiArea:

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

scriptPath = os.path.dirname(os.path.realpath(__file__))
uiFile = os.path.join(scriptPath, "mainwindow.ui")


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)
        self.initUI()

    def initUI(self):
        # load the UI page
        self.ui_main = uic.loadUi(uiFile, self)
        self.action1.triggered.connect(lambda: self.fileBarTrig("test"))

    def fileBarTrig(self, p):
        sw1 = self.mdiArea.addSubWindow(self.subwindow)
        sw1.show()
        sw2 = self.mdiArea.addSubWindow(self.subwindow_2)
        sw2.show()
        self.mdiArea.tileSubWindows()


def main():
    app = QtWidgets.QApplication(sys.argv)
    main = MainWindow()
    main.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()
person eyllanesc    schedule 09.06.2020
comment
Спасибо за помощь! Вы также знаете, как я могу закрыть подокно с помощью кнопки X с возможностью открыть его позже? Если я нажму кнопку X в одном из подокнов, а затем повторно запущу fileBarTrig, чтобы снова открыть подокно, я получу сообщение об ошибке, говорящее о том, что обернутый объект C/C++ типа QWidget был удален. Я пробовал использовать sw1.setAttribute(Qt.WA_DeleteOnClose, False), и это работает, однако элементы управления с кнопками также удаляются и больше не появляются. - person tmorgan497; 10.06.2020