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 __del__(self):
108  self._dock_widget.removeEventFilter(self)
109 
110  def connect_button(self, button_id, callback):
111  button = self._extra_buttons.get(button_id, None)
112  if button is None:
113  qWarning('DockWidgetTitleBar.connect_button(): unknown button_id: %s' % button_id)
114  return
115  button.clicked.connect(callback)
116 
117  def connect_close_button(self, callback):
118  self._close_callbacks.append(callback)
119 
120  def _close_clicked(self):
121  for callback in self._close_callbacks:
122  callback(self.parent())
123 
124  def show_button(self, button_id, visibility=True):
125  button = self._extra_buttons.get(button_id, None)
126  if button is None:
127  qWarning('DockWidgetTitleBar.show_button(): unknown button_id: %s' % button_id)
128  return
129  button.setVisible(visibility)
130 
131  def hide_button(self, button_id):
132  self.show_button(button_id, False)
133 
134  def eventFilter(self, obj, event):
135  if event.type() in self._event_callbacks:
136  ret_val = self._event_callbacks[event.type()](obj, event)
137  if ret_val is not None:
138  return ret_val
139  if event.type() == event.ContextMenu and obj == self.title_label:
140  menu = QMenu(self)
141  rename_action = menu.addAction(self.tr('Rename dock widget'))
142  action = menu.exec_(self.mapToGlobal(event.pos()))
143  if action == rename_action:
144  self.title_label.hide()
145  self.title_edit.setText(self.title_label.text())
146  self.title_edit.show()
147  self.title_edit.setFocus()
148  return True
149  return QObject.eventFilter(self, obj, event)
150 
151  def _update_icon(self, *args):
152  pixmap = None
153  if self.parentWidget().windowIcon():
154  pixmap = self.parentWidget().windowIcon().pixmap(self.close_button.iconSize())
155  self.icon_label.setPixmap(pixmap)
156 
157  def _update_title(self, *args):
158  self.title_label.setText(self.parentWidget().windowTitle())
159 
160  def _toggle_dockable(self, enabled):
161  dock_widget = self.parentWidget()
162  if enabled:
163  dock_widget.setAllowedAreas(Qt.AllDockWidgetAreas)
164  else:
165  dock_widget.setAllowedAreas(Qt.NoDockWidgetArea)
166 
167  def _toggle_floating(self):
168  dock_widget = self.parentWidget()
169  dock_widget.setFloating(not dock_widget.isFloating())
170 
172  dock_widget = self.parentWidget()
173  dock_widget.hide()
174 
175  def _features_changed(self, features=None):
176  if features is None:
177  features = self.parentWidget().features()
178 
179  closable = bool(features & QDockWidget.DockWidgetClosable)
180  self.close_button.setVisible(closable)
181  self.reload_button.setVisible(closable)
182 
183  movable = bool(features & QDockWidget.DockWidgetMovable)
184  self.dockable_button.setChecked(movable)
185  self._toggle_dockable(self.dockable_button.isChecked())
186  self.dockable_button.setVisible(movable)
187  self.float_button.setVisible(movable)
188  self.minimize_button.setVisible(movable)
189 
190  def save_settings(self, settings):
191  settings.set_value('dock_widget_title', self._dock_widget.windowTitle())
192 
193  # skip saving dockable flag when layout is frozen
194  movable = bool(self.parentWidget().features() & QDockWidget.DockWidgetMovable)
195  if movable:
196  settings.set_value('dockable', self.dockable_button.isChecked())
197 
198  def restore_settings(self, settings):
199  dock_widget_title = settings.value('dock_widget_title', None)
200  if dock_widget_title is not None:
201  self.title_label.setText(dock_widget_title)
202  self._dock_widget.setWindowTitle(dock_widget_title)
203 
204  dockable = settings.value('dockable', True) in [True, 'true']
205  # only allow dockable when layout is not frozen
206  movable = bool(self.parentWidget().features() & QDockWidget.DockWidgetMovable)
207  self.dockable_button.setChecked(dockable and movable)
208  self._toggle_dockable(self.dockable_button.isChecked())
209 
210  def _finished_editing(self):
211  self.title_edit.hide()
212  self.title_label.show()
213 
215  if self.title_edit.text():
216  self.title_label.setText(self.title_edit.text())
217  self._dock_widget.setWindowTitle(self.title_edit.text())
218 
219 
220 if __name__ == '__main__':
221  import sys
222  from python_qt_binding.QtGui import QApplication
223  from qt_gui.dockable_main_window import DockableMainWindow
224 
225  app = QApplication(sys.argv)
226 
228 
229  dock1 = QDockWidget('dockwidget1', win)
230  win.addDockWidget(Qt.LeftDockWidgetArea, dock1)
231  title_bar = DockWidgetTitleBar(dock1)
232  dock1.setTitleBarWidget(title_bar)
233 
234  dock2 = QDockWidget('dockwidget2')
235  win.addDockWidget(Qt.RightDockWidgetArea, dock2)
236  title_bar = DockWidgetTitleBar(dock2)
237  dock2.setTitleBarWidget(title_bar)
238 
239  win.resize(640, 480)
240  win.show()
241 
242  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 Tue Apr 13 2021 03:03:12