如何使用 qtDesigner 将子窗口停靠在 pyqt5 的 MDI 区域中
How do I dock a subwindow in an MDI Area in pyqt5 using qtDesigner
我正在尝试在 pyqt5 的 MDI 区域中创建一个子 window,为我的主 window 使用 .ui 文件。当我触发显示 subwindow 的操作时,它显示为单独的 window(未按预期停靠在 MDI 区域中)。我已经尝试通过本教程 (codeloop.org MDI Area Tutorial) 添加 subwindow,它工作正常,但我无法通过加载 .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 运行 未停靠子window
QMdiArea中没有插入widget,好像是bug,至少是能力不足,分析一下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()
我正在尝试在 pyqt5 的 MDI 区域中创建一个子 window,为我的主 window 使用 .ui 文件。当我触发显示 subwindow 的操作时,它显示为单独的 window(未按预期停靠在 MDI 区域中)。我已经尝试通过本教程 (codeloop.org MDI Area Tutorial) 添加 subwindow,它工作正常,但我无法通过加载 .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 运行 未停靠子window
QMdiArea中没有插入widget,好像是bug,至少是能力不足,分析一下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()