python - Inserted tabs not showing in QTabWidget despite show() called -
i have qtabwidget in pyqt provides possibility tear off tabs , re-attach them when closed. works except newly attached tabs aren't showing. blank widget showing , widget shown after current tab has been changed , changed back.
i've searched stackoverflow , answers similar problems have pointed out added widget's show()
-method needs called after new tab added. tried newly added tab still not showing.
slimmed down example code:
from pyqt4 import qtgui, qtcore class detachabletabwidget(qtgui.qtabwidget): """ subclass of qtabwidget provides ability detach tabs , making floating windows them can reattached. """ def __init__(self, *args, **kwargs): super(detachabletabwidget, self).__init__(*args, **kwargs) self.settabbar(_detachabletabbar()) def detach_tab(self, i): """ make floating window of tab. :param i: index of tab detach """ teared_widget = self.widget(i) widget_name = self.tabtext(i) # shift index left , remove tab. self.setcurrentindex(self.currentindex() - 1 if self.currentindex() > 0 else 0) self.removetab(i) # store widgets window-flags , close event. teared_widget._flags = teared_widget.windowflags() teared_widget._close = teared_widget.closeevent # make stand-alone window. teared_widget.setwindowflags(qtcore.qt.window) teared_widget.show() # redirect windows close-event reattachment. teared_widget.closeevent = lambda event: self.attach_tab(teared_widget, widget_name) def attach_tab(self, widget, name): """ attach widget when receiving signal child-window. :param widget: :class:`qtgui.qwidget` :param name: name of attached widget """ widget.setwindowflags(widget._flags) widget.closeevent = widget._close self.addtab(widget, name) self.setcurrentwidget(widget) self.currentwidget().show() class _detachabletabbar(qtgui.qtabbar): def __init__(self, *args, **kwargs): super(_detachabletabbar, self).__init__(*args, **kwargs) self._start_drag_pos = none self._has_dragged = false self.setmovable(true) def mousepressevent(self, event): # keep track of drag-starts. self._start_drag_pos = event.globalpos() super(_detachabletabbar, self).mousepressevent(event) def mousemoveevent(self, event): # if tab detached, nothing. if self._has_dragged: return # detach-tab if drag in y-direction large enough. if abs((self._start_drag_pos - event.globalpos()).y()) >= qtgui.qapplication.startdragdistance()*8: self._has_dragged = true self.parent().detach_tab(self.currentindex()) def mousereleaseevent(self, event): self._has_dragged = false if __name__ == '__main__': import sys app = qtgui.qapplication(sys.argv) window = qtgui.qmainwindow() widget = detachabletabwidget() widget.addtab(qtgui.qlabel('tab 1'), 'tab 1') widget.addtab(qtgui.qlabel('tab 2'), 'tab 2') window.setcentralwidget(widget) window.show() sys.exit(app.exec_())
it seems when accept qcloseevent (default behavior) widget hidden @ end of closeevent handler. call show()
occurs before end of handler. solution ignore qcloseevent.
... teared_widget.closeevent = lambda event: self.attach_tab(teared_widget, widget_name, event) def attach_tab(self, widget, name, event): """ attach widget when receiving signal child-window. :param widget: :class:`qtgui.qwidget` :param name: name of attached widget :param event: close event """ widget.setwindowflags(widget._flags) widget.closeevent = widget._close self.addtab(widget, name) self.setcurrentwidget(widget) event.ignore()
Comments
Post a Comment