2014-12-16 2 views
1

나는 탭을 떼어 내고 닫을 때 다시 부착 할 수있는 QTab 위젯을 PyQt에 가지고 있습니다. 새로 첨부 된 탭이 즉시 표시되지 않는 것을 제외하면 잘 작동합니다. 비어있는 위젯이 표시되고 현재 탭이 변경되고 다시 변경된 후에 만 ​​위젯이 표시됩니다.show()라고 불렀음에도 불구하고 QTabWidget에 삽입 된 탭이 표시되지 않음

StackOverflow를 검색 한 결과 유사한 문제에 대한 답변으로 새로운 탭을 추가 한 후에 추가 된 위젯의 show() -method를 호출해야한다고 지적했습니다. 나는 그것을 시도했지만 새로 추가 된 탭 여전히 표시되지 않습니다.

몸매는 여전 하구나 예제 코드 :

from PyQt4 import QtGui, QtCore 


class DetachableTabWidget(QtGui.QTabWidget): 

    """ Subclass of QTabWidget which provides the ability to detach 
    tabs and making floating windows from them which can be 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 to detach 
     """ 
     teared_widget = self.widget(i) 
     widget_name = self.tabText(i) 

     # Shift index to the left and remove tab. 
     self.setCurrentIndex(self.currentIndex() - 1 if self.currentIndex() > 0 else 0) 
     self.removeTab(i) 

     # Store widgets window-flags and 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 into reattachment. 
     teared_widget.closeEvent = lambda event: self.attach_tab(teared_widget, widget_name) 

    def attach_tab(self, widget, name): 
     """ Attach widget when receiving signal from 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 where drag-starts. 
     self._start_drag_pos = event.globalPos() 
     super(_DetachableTabBar, self).mousePressEvent(event) 

    def mouseMoveEvent(self, event): 
     # If tab is already detached, do nothing. 
     if self._has_dragged: 
      return 

     # Detach-tab if drag in y-direction is 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_()) 

답변

3

그것은 당신이 QCloseEvent (기본 동작) 위젯은 사용자의 closeEvent 핸들러의 말에 숨겨져을 받아 들일 때보다 같다. 그러나 show()에 대한 전화는 처리기가 끝나기 전에 발생합니다. 해결 방법은 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 from 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() 
+0

덕분에 지금은 감사합니다. – RickardSjogren

관련 문제