Вы знаете, что когда вы скрываете строку заголовка пристыкованного QDockWidget, она больше не может перемещаться, верно?
Дело не так просто. Я закончил тем, что сшил несколько событий вместе:
У меня есть режим упорядочивания (редактирования) и режим просмотра (нормальный). В режиме редактирования панели заголовка видны, что позволяет перетаскивать панели при необходимости. Кнопка на панели инструментов отвечает за переключение режимов. В вашем случае вы можете использовать только режим просмотра (режим упорядочивания отключен).
Когда панель отсоединена, а форма не установлена в режим редактирования, строка заголовка отсоединенной панели будет сброшена на None
, что приводит к отображению границ окна, в то время как закрепленные панели имеют скрытую строку заголовка.
Когда отсоединенные панели закрепляются, если форма находится в режиме просмотра, для строки заголовка устанавливается значение сам виджет, тем самым скрыв его. Сигнал topLevelChanged
используется для запуска проверки и изменения.
В результате windows могут быть упорядочены разными способами, пристыкованы или отстыкованы, с простым пользовательским интерфейсом. Обратите внимание, что хотя в этом примере вы можете установить закрываемые вкладки, кнопки закрытия в этом примере не обрабатываются.
Вот полнофункциональное тестовое приложение:
from PyQt5 import QtCore, QtGui
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QWidget, QMainWindow, QTextEdit, QDockWidget, QToolBar, QTabWidget, QAction, QLayout, QTabBar
import PyQt5.QtWidgets
from PyQt5.QtGui import QIcon, QPixmap
#from PyQt5.QtCore import QMainWindow
_DOCK_OPTS = PyQt5.QtWidgets.QMainWindow.AllowNestedDocks
_DOCK_OPTS |= PyQt5.QtWidgets.QMainWindow.AllowTabbedDocks
class Window(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setWindowTitle("Test")
tb = self.addToolBar("Test")
self.ShowTitleBars = False
secondQMainWindow = QMainWindow()
self.setTabPosition (Qt.LeftDockWidgetArea, QTabWidget.North)
self.central = secondQMainWindow
self.setDockOptions(_DOCK_OPTS)
self.dw1 = QDockWidget("One")
self.dw1.topLevelChanged.connect(self.HideTitleBar)
self.dw1.setTitleBarWidget(QWidget(self.dw1))
textArea = QTextEdit()
textArea.setText("Text area 1")
self.dw1.setWidget(textArea)
self.dw2 = QDockWidget("Two")
textArea2 = QTextEdit()
textArea2.setText("Text area 2")
self.dw2.setWidget(textArea2)
self.dw2.topLevelChanged.connect(self.HideTitleBar)
self.dw2.setTitleBarWidget(QWidget(self.dw2))
self.addDockWidget(Qt.LeftDockWidgetArea, self.dw1)
self.addDockWidget(Qt.RightDockWidgetArea, self.dw2)
self.tabifyDockWidget(self.dw1, self.dw2)
self.dw3 = QDockWidget("Three")
self.dw3.topLevelChanged.connect(self.HideTitleBar)
self.dw3.setTitleBarWidget(QWidget(self.dw3))
textArea3 = QTextEdit()
textArea3.setText("Text area 3")
self.dw3.setWidget(textArea3)
self.addDockWidget(Qt.LeftDockWidgetArea, self.dw3)
barOn = QAction("Tabs closable",self)
barOn.triggered.connect(self.CountTabWidgetsInTopWindow)
tb.addAction(barOn)
barOff = QAction("Anotherbar",self)
#barOff.triggered.connect(self.ToogleTwo)
tb.addAction(barOff)
barTog = QAction("Toggle Title Bars",self)
barTog.setCheckable(True)
barTog.triggered.connect(self.ToogleTitles2)
tb.addAction(barTog)
def ToogleTwo(self):
self.dw1.setTitleBarWidget(QWidget(self.dw1))
self.dw2.setTitleBarWidget(QWidget(self.dw2))
self.dw3.setTitleBarWidget(QWidget(self.dw3))
print("Test OFF")
def ToogleTitles(self):
#self.dw1.setTitleBarWidget(self.dw1)
self.dw1.setTitleBarWidget(None)
self.dw2.setTitleBarWidget(None)
self.dw3.setTitleBarWidget(None)
print("Test ON")
def SetTabsClosable(self):
for widget in self.children():
if isinstance(widget, QTabBar):
widget.setTabsClosable(True)
def CountTabWidgetsInTopWindow(self):
for widget in self.children():
if isinstance(widget, QTabBar):
widget.setTabsClosable(True)
else:
print("QTabWidget " + widget.objectName() + " -- " + widget.__class__.__name__)
print("Counted.")
def HideTitleBar(self):
dockw = self.sender()
if dockw.isFloating() == False and self.ShowTitleBars == False:
dockw.setTitleBarWidget(QWidget(dockw))
def ToogleTitles2(self):
if self.ShowTitleBars == True:
self.ShowTitleBars = False
else:
self.ShowTitleBars = True
for widget in self.children():
if isinstance(widget, QDockWidget):
if widget.titleBarWidget() == None and self.ShowTitleBars == False:
if widget.isFloating() == False:
widget.setTitleBarWidget(QWidget(widget))
else:
widget.setTitleBarWidget(None)
print("Test Toggle")
if __name__ == '__main__':
import sys
app = PyQt5.QtWidgets.QApplication(sys.argv)
window = Window()
window.show()
app.exec_()