[PyQt] Collapsible Dock Widget??
Giovanni Bajo
rasky at develer.com
Wed Jul 23 14:40:10 BST 2008
On 7/23/2008 2:43 PM, Darryl Wallace wrote:
> Yeah just like that. Except I would also want to put a toggle button on
> the title bar of the widget so that toggle between auto-hide and staying
> open.
>
> Any tips on how to get started with that auto-hide functionality?
I'm attaching a self-contained object that does this for you. Create
this object within the main window, and initialize it by specifying
which dock widget area it must handle auto-hide for.
Notice that it handles auto-hide for *dock widgets*, not for *toolbars*.
To enable/disable auto-hide behaviour, I would just destroy this object
and reecrate it. Notice that you can call "showDockWidgets()" before
destruction to force all dock widgets to be visible again.
I had already submitted this code to Trolltech to push for inclusion of
such a feature in QMainWindow, but those guys are lazy :)
There's also one known bug: sometimes, after the widgets are shown, the
dock widget layout changes their dimension. I think this is a bug in the
layout code (it's the layout created by the main window to handle the
dock widgets) but I wasn't able to trace it within Qt's source code.
I would appreciate if you contribute back enhancements.
--
Giovanni Bajo
Develer S.r.l.
http://www.develer.com
-------------- next part --------------
#!/usr/bin/env python
#-*- coding: utf-8 -*-
from PyQt4.Qt import *
class QAutoHideDockWidgets(QToolBar):
"""
QMainWindow "mixin" which provides auto-hiding support for dock widgets
(not toolbars).
"""
DOCK_AREA_TO_TB = {
Qt.LeftDockWidgetArea: Qt.LeftToolBarArea,
Qt.RightDockWidgetArea: Qt.RightToolBarArea,
Qt.TopDockWidgetArea: Qt.TopToolBarArea,
Qt.BottomDockWidgetArea: Qt.BottomToolBarArea,
}
def __init__(self, area, parent, name="AUTO_HIDE"):
QToolBar.__init__(self, parent)
assert isinstance(parent, QMainWindow)
assert area in self.DOCK_AREA_TO_TB
self._area = area
self.setObjectName(name)
self.setWindowTitle(name)
self.setFloatable(False)
self.setMovable(False)
w = QWidget(None)
w.resize(10, 100)
self.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.MinimumExpanding))
self.addWidget(w)
self.setAllowedAreas(self.DOCK_AREA_TO_TB[self._area])
self.parent().addToolBar(self.DOCK_AREA_TO_TB[self._area], self)
self.parent().centralWidget().installEventFilter(self)
self.setVisible(False)
self.hideDockWidgets()
def _dockWidgets(self):
mw = self.parent()
for w in mw.findChildren(QDockWidget):
if mw.dockWidgetArea(w) == self._area and not w.isFloating():
yield w
def paintEvent(self, event):
p = QPainter(self)
p.setPen(Qt.black)
p.setBrush(Qt.black)
if self._area == Qt.LeftDockWidgetArea:
p.translate(QPointF(0, self.height() / 2 - 5))
p.drawPolygon(QPointF(2,0), QPointF(8,5), QPointF(2,10))
elif self._area == Qt.RightDockWidgetArea:
p.translate(QPointF(0, self.height() / 2 - 5))
p.drawPolygon(QPointF(8,0), QPointF(2,5), QPointF(8,10))
def _multiSetVisible(self, widgets, state):
if state:
self.setVisible(False)
for w in widgets:
w.setUpdatesEnabled(False)
for w in widgets:
w.setVisible(state)
for w in widgets:
w.setUpdatesEnabled(True)
if not state and widgets:
self.setVisible(True)
def enterEvent(self, event):
self.showDockWidgets()
def eventFilter(self, obj, event):
if event.type() == QEvent.Enter:
assert obj == self.parent().centralWidget()
self.hideDockWidgets()
return False
def setDockWidgetsVisible(self, state):
self._multiSetVisible(list(self._dockWidgets()), state)
def showDockWidgets(self): self.setDockWidgetsVisible(True)
def hideDockWidgets(self): self.setDockWidgetsVisible(False)
More information about the PyQt
mailing list