dock_widget_title_bar.py
Go to the documentation of this file.
1 # Copyright (c) 2011, Dirk Thomas, Dorian Scholz, TU Darmstadt
2 # All rights reserved.
3 #
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions
6 # are met:
7 #
8 # * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above
11 # copyright notice, this list of conditions and the following
12 # disclaimer in the documentation and/or other materials provided
13 # with the distribution.
14 # * Neither the name of the TU Darmstadt nor the names of its
15 # contributors may be used to endorse or promote products derived
16 # from this software without specific prior written permission.
17 #
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 # POSSIBILITY OF SUCH DAMAGE.
30 
31 import os
32 
33 from python_qt_binding import loadUi
34 from python_qt_binding.QtCore import QEvent, QObject, Qt, qWarning
35 from python_qt_binding.QtGui import QIcon
36 from python_qt_binding.QtWidgets import QDockWidget, QMenu, QWidget
37 
38 
39 class DockWidgetTitleBar(QWidget):
40  """Title bar for dock widgets providing custom actions."""
41 
42  def __init__(self, dock_widget, qtgui_path, hide_title=False):
43  super(DockWidgetTitleBar, self).__init__(dock_widget)
44  self._dock_widget = dock_widget
45 
46  ui_file = os.path.join(qtgui_path, 'resource', 'dock_widget_title_bar.ui')
47  loadUi(ui_file, self)
48  self._extra_buttons = {
49  'configuration': self.configuration_button,
50  'reload': self.reload_button,
51  'help': self.help_button,
52  'close': self.close_button,
53  }
54 
55  icon = QIcon.fromTheme('emblem-system')
56  if not icon.isNull():
57  self.configuration_button.setIcon(icon)
58  self.configuration_button.setText('')
59  icon = QIcon.fromTheme('view-refresh')
60  if not icon.isNull():
61  self.reload_button.setIcon(icon)
62  self.reload_button.setText('')
63  icon = QIcon.fromTheme('help-browser')
64  if not icon.isNull():
65  self.help_button.setIcon(icon)
66  self.help_button.setText('')
67 
68  icon = QIcon.fromTheme('window-close')
69  if not icon.isNull():
70  self.close_button.setIcon(icon)
71  self.close_button.setText('')
72  self.close_button.clicked.connect(self._close_clicked)
73 
74  self.float_button.clicked.connect(self._toggle_floating)
75  self.dockable_button.clicked[bool].connect(self._toggle_dockable)
76  self.minimize_button.clicked.connect(self._minimize_dock_widget)
77 
78  self._dock_widget.featuresChanged.connect(self._features_changed)
79  self._features_changed()
80 
81  self._update_icon()
82  self._update_title()
83 
84  self._close_callbacks = []
86  QEvent.WindowIconChange: self._update_icon,
87  QEvent.WindowTitleChange: self._update_title,
88  }
89  self._dock_widget.installEventFilter(self)
90 
91  self.title_label.installEventFilter(self)
92  self.title_edit.hide()
93  self.title_edit.editingFinished.connect(self._finished_editing)
94  self.title_edit.returnPressed.connect(self._update_title_label)
95 
96  if hide_title:
97  # hide all except the configuration button if present
98  self.icon_label.hide()
99  self.title_label.hide()
100  self.dockable_button.hide()
101  self.reload_button.hide()
102  self.help_button.hide()
103  self.minimize_button.hide()
104  self.float_button.hide()
105  self.close_button.hide()
106 
107  def connect_button(self, button_id, callback):
108  button = self._extra_buttons.get(button_id, None)
109  if button is None:
110  qWarning('DockWidgetTitleBar.connect_button(): unknown button_id: %s' % button_id)
111  return
112  button.clicked.connect(callback)
113 
114  def connect_close_button(self, callback):
115  self._close_callbacks.append(callback)
116 
117  def _close_clicked(self):
118  for callback in self._close_callbacks:
119  callback(self.parent())
120 
121  def show_button(self, button_id, visibility=True):
122  button = self._extra_buttons.get(button_id, None)
123  if button is None:
124  qWarning('DockWidgetTitleBar.show_button(): unknown button_id: %s' % button_id)
125  return
126  button.setVisible(visibility)
127 
128  def hide_button(self, button_id):
129  self.show_button(button_id, False)
130 
131  def eventFilter(self, obj, event):
132  if event.type() in self._event_callbacks:
133  ret_val = self._event_callbacks[event.type()](obj, event)
134  if ret_val is not None:
135  return ret_val
136  if event.type() == event.ContextMenu and obj == self.title_label:
137  menu = QMenu(self)
138  rename_action = menu.addAction(self.tr('Rename dock widget'))
139  action = menu.exec_(self.mapToGlobal(event.pos()))
140  if action == rename_action:
141  self.title_label.hide()
142  self.title_edit.setText(self.title_label.text())
143  self.title_edit.show()
144  self.title_edit.setFocus()
145  return True
146  return QObject.eventFilter(self, obj, event)
147 
148  def _update_icon(self, *args):
149  pixmap = None
150  if self.parentWidget().windowIcon():
151  pixmap = self.parentWidget().windowIcon().pixmap(self.close_button.iconSize())
152  self.icon_label.setPixmap(pixmap)
153 
154  def _update_title(self, *args):
155  self.title_label.setText(self.parentWidget().windowTitle())
156 
157  def _toggle_dockable(self, enabled):
158  dock_widget = self.parentWidget()
159  if enabled:
160  dock_widget.setAllowedAreas(Qt.AllDockWidgetAreas)
161  else:
162  dock_widget.setAllowedAreas(Qt.NoDockWidgetArea)
163 
164  def _toggle_floating(self):
165  dock_widget = self.parentWidget()
166  dock_widget.setFloating(not dock_widget.isFloating())
167 
169  dock_widget = self.parentWidget()
170  dock_widget.hide()
171 
172  def _features_changed(self, features=None):
173  if features is None:
174  features = self.parentWidget().features()
175 
176  closable = bool(features & QDockWidget.DockWidgetClosable)
177  self.close_button.setVisible(closable)
178  self.reload_button.setVisible(closable)
179 
180  movable = bool(features & QDockWidget.DockWidgetMovable)
181  self.dockable_button.setChecked(movable)
182  self._toggle_dockable(self.dockable_button.isChecked())
183  self.dockable_button.setVisible(movable)
184  self.float_button.setVisible(movable)
185  self.minimize_button.setVisible(movable)
186 
187  def save_settings(self, settings):
188  settings.set_value('dock_widget_title', self._dock_widget.windowTitle())
189 
190  # skip saving dockable flag when layout is frozen
191  movable = bool(self.parentWidget().features() & QDockWidget.DockWidgetMovable)
192  if movable:
193  settings.set_value('dockable', self.dockable_button.isChecked())
194 
195  def restore_settings(self, settings):
196  dock_widget_title = settings.value('dock_widget_title', None)
197  if dock_widget_title is not None:
198  self.title_label.setText(dock_widget_title)
199  self._dock_widget.setWindowTitle(dock_widget_title)
200 
201  dockable = settings.value('dockable', True) in [True, 'true']
202  # only allow dockable when layout is not frozen
203  movable = bool(self.parentWidget().features() & QDockWidget.DockWidgetMovable)
204  self.dockable_button.setChecked(dockable and movable)
205  self._toggle_dockable(self.dockable_button.isChecked())
206 
207  def _finished_editing(self):
208  self.title_edit.hide()
209  self.title_label.show()
210 
212  if self.title_edit.text():
213  self.title_label.setText(self.title_edit.text())
214  self._dock_widget.setWindowTitle(self.title_edit.text())
215 
216 
217 if __name__ == '__main__':
218  import sys
219  from python_qt_binding.QtGui import QApplication
220  from qt_gui.dockable_main_window import DockableMainWindow
221 
222  app = QApplication(sys.argv)
223 
225 
226  dock1 = QDockWidget('dockwidget1', win)
227  win.addDockWidget(Qt.LeftDockWidgetArea, dock1)
228  title_bar = DockWidgetTitleBar(dock1)
229  dock1.setTitleBarWidget(title_bar)
230 
231  dock2 = QDockWidget('dockwidget2')
232  win.addDockWidget(Qt.RightDockWidgetArea, dock2)
233  title_bar = DockWidgetTitleBar(dock2)
234  dock2.setTitleBarWidget(title_bar)
235 
236  win.resize(640, 480)
237  win.show()
238 
239  app.exec_()
def __init__(self, dock_widget, qtgui_path, hide_title=False)
def show_button(self, button_id, visibility=True)


qt_gui
Author(s): Dirk Thomas
autogenerated on Fri Jun 24 2022 02:42:37