簡體   English   中英

將標簽從 QtabBar 拖放到拆分的 Widget PyQt Qt 中的其他 QtabBar

[英]drag and drop a Tab from a QtabBar to other QtabBar in a splitted Widget PyQt Qt

我該如何存檔: - 我需要將一個選項卡從其 tabBar 拖放到拆分小部件中的其他 tabBar? 我已經將 QtabBar 子類化並實現了拖放事件,我已經可以使用正確的像素圖等拖動它,並且我也可以將它放到同一個 tabBar 中,但不能放到另一個 tabBar 中……在輸出中得到這個錯誤告訴我我沒有提供正確的參數,這里是代碼,我簡化了 make it 和 example,以及窗口的 .JPG。

class EsceneTest(qg.QMainWindow):
    def __init__(self,parent=getMayaWindow()):
        super(EsceneTest,self).__init__(parent)
        #---------------------------------------------------------#        
        #check for open Window first
        winName = windowTitle
        if cmds.window(winName, exists =1):
            cmds.deleteUI(winName, wnd=True)

        self.setAttribute(qc.Qt.WA_DeleteOnClose) 
        self._initUI()      

    def _initUI(self):                     
        self.setObjectName(windowObject)
        self.setWindowTitle(windowTitle)
        self.setMinimumWidth(450)
        self.setMinimumHeight(500)
        self.resize(1080, 800) # re-size the window
        centralWidget = qg.QWidget()
        centralWidget.setObjectName('centralWidget')
        self.setCentralWidget(centralWidget)
        central_layout = qg.QVBoxLayout(centralWidget)

        ######################
        # tab container
        #
        self.tabWidget = qg.QTabWidget()
        self.tabWidget.setAcceptDrops(True)
        self.tab_layout = qg.QVBoxLayout(self.tabWidget)
        central_layout.addWidget(self.tabWidget)

        #######################
        # TabBar
        #                 
        custom_tabbar = ColtabBar()
        self.tabWidget.setTabBar(custom_tabbar)        

        #######################
        # ViewportTab
        #         
        tabCentral_wdg = qg.QWidget()
        self.top_lyt = qg.QVBoxLayout(tabCentral_wdg)
        self.tab_layout.addLayout(self.top_lyt)       

        fixedHBox_lyt = qg.QHBoxLayout()
        self.top_lyt.addLayout(fixedHBox_lyt)   
        self.tabWidget.addTab(tabCentral_wdg,'- Viewport')

        #######################
        # Example ExtraTab
        #        
        tabTwo_wdg = qg.QWidget()
        tabTwo_wdg_lyt = qg.QHBoxLayout(tabTwo_wdg)
        self.tab_layout.addLayout(tabTwo_wdg_lyt)        
        label = qg.QLabel(' -- This is an example -- ')
        label.setStyleSheet("""
                            background : qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgb(53, 57, 60), stop:1 rgb(33, 34, 36));
                            border-style : none;
                            font-size: 40px;
                            font-family: Calibri;
                            color : rgb(200,200,100);
                        """)
        label.setAlignment(qc.Qt.AlignVCenter | qc.Qt.AlignHCenter )
        tabTwo_wdg_lyt.addWidget(label)       
        tab_panel_lyt = qg.QVBoxLayout(label)    
        self.tabWidget.addTab(tabTwo_wdg,'- ExtraExample') 

        ############################
        #   Q Splitter Widget to insert the dragged Tabs
        #
        split = qg.QSplitter(qc.Qt.Orientation.Vertical, self)
        central_layout.addWidget(split)
        tab_splitted = qg.QTabWidget()
        split.setLayout(qg.QVBoxLayout())
        split.insertWidget(0,tab_splitted)
        tabBar_2 = ColtabBar()
        tab_splitted.setTabBar(tabBar_2)
        tabBar_2.addTab('- Insert-Here')
#---------------------------------------------------------------------------------------------#

class ColtabBar(qg.QTabBar):
    def __init__(self):
        super(ColtabBar, self).__init__()
        self.indexTab = None        
        self.setAcceptDrops(True)   

    ##################################
    # Events
    def mouseMoveEvent(self, e):
        if e.buttons() != qc.Qt.MiddleButton:
            return

        globalPos = self.mapToGlobal(e.pos())
        posInTab = self.mapFromGlobal(globalPos)
        self.indexTab = self.tabAt(e.pos())
        tabRect = self.tabRect(self.indexTab)


        pixmap = qg.QPixmap(tabRect.size())
        self.render(pixmap,qc.QPoint(),qg.QRegion(tabRect))
        mimeData = qc.QMimeData()
        drag = qg.QDrag(self)
        drag.setMimeData(mimeData)
        drag.setPixmap(pixmap)

        cursor = qg.QCursor(qc.Qt.OpenHandCursor)    
        drag.setHotSpot(e.pos() - posInTab)
        drag.setDragCursor(cursor.pixmap(),qc.Qt.MoveAction)       
        dropAction = drag.exec_(qc.Qt.MoveAction)


    def mousePressEvent(self, e):
        #super(qg.QWidget).mousePressEvent(e)
        if e.button() == qc.Qt.RightButton:
            print('press')

        if e.button() == qc.Qt.LeftButton:            
            globalPos = self.mapToGlobal(e.pos())
            posInTab = self.mapFromGlobal(globalPos)
            self.indexTab = self.tabAt(e.pos())
            self.setCurrentIndex(self.indexTab)

    def dragEnterEvent(self, e):
        e.accept()


    def dropEvent(self, e):
        e.setDropAction(qc.Qt.MoveAction)
        e.accept()        
        self.insertTab(self.indexTab, self.tabText(self.indexTab)) 
        self.removeTab(self.indexTab)

ColtabBar是我執行拖放事件的子類。

圖像 - > 例子

幾個小時后,今天在網上吃了很多 Qt 頁面,我按照自己的方式做了,現在我可以將標簽從一個 tabBar 拖放到另一個 tabBar,反之亦然,而不僅僅是從選擇當前選項卡,我可以在選項卡欄中選擇我想要的每個選項卡,並在拖動時向我顯示小選項卡的像素圖...

這是代碼:

** 編輯 **

我使它更加防彈,當我使用超過 2 個標簽的索引時,我有一個錯誤,現在工作得更好,當我把它放在同一個小部件中時,它返回事件而不執行代碼,加上懸停也可以使用鼠標右鍵選擇選項卡.. 我希望這可以幫助將來的任何人。

TABINDEX = int()

def getTabIndex(index):
    global TABINDEX
    if index == -1 or index == TABINDEX:
        return
    TABINDEX = index
    print (TABINDEX)
    return TABINDEX


class ColtTab(qg.QTabWidget):
    def __init__(self):
        super(ColtTab,self).__init__()
        self.setAcceptDrops(True)
        self.tabBar = self.tabBar()
        self.tabBar.setMouseTracking(True)
        self.setDocumentMode(True)
        self.indexTab = int()
        self.setMovable(True)
        self.setStyleSheet(style_sheet_file)


    # test for hovering and selecting tabs automatic while mouser over then - not working for now...
    def eventFilter(self, obj, event):
        if obj == self.tabBar:
            if event.type() == qc.QEvent.MouseMove:
                index=self.tabBar.tabAt(event.pos())
                self.tabBar.setCurrentIndex (index)
                return True
            else:
                return
        else:
            return

    ##################################
    # Events
    #
    def mouseMoveEvent(self, e):
        if e.buttons() != qc.Qt.MiddleButton:
            return

        globalPos = self.mapToGlobal(e.pos())
        #print(globalPos)
        tabBar = self.tabBar
        #print(tabBar)
        posInTab = tabBar.mapFromGlobal(globalPos)
        #print(posInTab)
        self.indexTab = tabBar.tabAt(e.pos())
        #print(self.indexTab)
        tabRect = tabBar.tabRect(self.indexTab)
        #print(tabRect)
        #print(tabRect.size())

        pixmap = qg.QPixmap(tabRect.size())
        tabBar.render(pixmap,qc.QPoint(),qg.QRegion(tabRect))
        mimeData = qc.QMimeData()
        drag = qg.QDrag(tabBar)
        drag.setMimeData(mimeData)
        drag.setPixmap(pixmap)
        cursor = qg.QCursor(qc.Qt.OpenHandCursor)
        drag.setHotSpot(e.pos() - posInTab)
        drag.setDragCursor(cursor.pixmap(),qc.Qt.MoveAction)
        dropAction = drag.exec_(qc.Qt.MoveAction)


    def mousePressEvent(self, e):
        if e.button() == qc.Qt.RightButton:
            self.tabBar.installEventFilter(self)
            print('Right button pressed')

        super(ColtTab, self).mousePressEvent(e)


    def dragEnterEvent(self, e):
        e.accept()
        if e.source().parentWidget() != self:
            return

        # Helper function for retrieving the Tab index into a global Var
        getTabIndex(self.indexOf(self.widget(self.indexTab)))


    def dragLeaveEvent(self,e):
        e.accept()


    def dropEvent(self, e):
        if e.source().parentWidget() == self:
            return

        e.setDropAction(qc.Qt.MoveAction)
        e.accept()
        counter = self.count()

        if counter == 0:
            self.addTab(e.source().parentWidget().widget(TABINDEX),e.source().tabText(TABINDEX))
        else:
            self.insertTab(counter + 1 ,e.source().parentWidget().widget(TABINDEX),e.source().tabText(TABINDEX))

        print ('Tab dropped')

    def mouseReleaseEvent(self, e):
        if e.button() == qc.Qt.RightButton:
            print('Right button released')
            self.tabBar.removeEventFilter(self)

        super(ColtTab, self).mouseReleaseEvent(e)


    #---------------------------------------------------------------------------------#

圖片->

示例:

發現這個線程很有用。 使用您的解決方案在 PyQt5 中創建了一個自包含的通用示例。 將來可能會幫助某人。

import sys

from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

class Tabs(QTabWidget):
    def __init__(self, parent):
        super().__init__(parent)
        self.parent = parent
        self.setAcceptDrops(True)
        self.tabBar = self.tabBar()
        self.tabBar.setMouseTracking(True)
        self.indexTab = None
        self.setMovable(True)

        self.addTab(QWidget(self), 'Tab One')
        self.addTab(QWidget(self), 'Tab Two')

    def mouseMoveEvent(self, e):
        if e.buttons() != Qt.RightButton:
            return

        globalPos = self.mapToGlobal(e.pos())
        tabBar = self.tabBar
        posInTab = tabBar.mapFromGlobal(globalPos)
        self.indexTab = tabBar.tabAt(e.pos())
        tabRect = tabBar.tabRect(self.indexTab)

        pixmap = QPixmap(tabRect.size())
        tabBar.render(pixmap,QPoint(),QRegion(tabRect))
        mimeData = QMimeData()
        drag = QDrag(tabBar)
        drag.setMimeData(mimeData)
        drag.setPixmap(pixmap)
        cursor = QCursor(Qt.OpenHandCursor)
        drag.setHotSpot(e.pos() - posInTab)
        drag.setDragCursor(cursor.pixmap(),Qt.MoveAction)
        dropAction = drag.exec_(Qt.MoveAction)


    def dragEnterEvent(self, e):
        e.accept()
        if e.source().parentWidget() != self:
            return

        print(self.indexOf(self.widget(self.indexTab)))
        self.parent.TABINDEX = self.indexOf(self.widget(self.indexTab))


    def dragLeaveEvent(self,e):
        e.accept()


    def dropEvent(self, e):
        print(self.parent.TABINDEX)
        if e.source().parentWidget() == self:
            return

        e.setDropAction(Qt.MoveAction)
        e.accept()
        counter = self.count()

        if counter == 0:
            self.addTab(e.source().parentWidget().widget(self.parent.TABINDEX),e.source().tabText(self.parent.TABINDEX))
        else:
            self.insertTab(counter + 1 ,e.source().parentWidget().widget(self.parent.TABINDEX),e.source().tabText(self.parent.TABINDEX))


class Window(QWidget):
    def __init__(self):

        super().__init__()

        self.TABINDEX = 0
        tabWidgetOne = Tabs(self)
        tabWidgetTwo = Tabs(self)

        layout = QHBoxLayout()

        self.moveWidget = None

        layout.addWidget(tabWidgetOne)
        layout.addWidget(tabWidgetTwo)

        self.setLayout(layout)

if __name__ == '__main__':

    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

這是從別人的代碼修改而來的,也許是上面的例子之一。

無論如何,這是選項卡到選項卡或選項卡到窗口拖/放選項卡內容的最小代碼。

from PyQt5.QtWidgets import QTabWidget
from PyQt5.QtCore import Qt, QPoint, QMimeData
from PyQt5.QtGui import QPixmap, QRegion, QDrag, QCursor

class TabWidget(QTabWidget):
   def __init__(self, parent=None, new=None):
      super().__init__(parent)
      self.setAcceptDrops(True)
      self.tabBar().setMouseTracking(True)
      self.setMovable(True)
      if new:
         TabWidget.setup(self)

   def __setstate__(self, data):
      self.__init__(new=False)
      self.setParent(data['parent'])
      for widget, tabname in data['tabs']:
         self.addTab(widget, tabname)
      TabWidget.setup(self)

   def __getstate__(self):
      data = {
         'parent' : self.parent(),
         'tabs' : [],
      }
      tab_list = data['tabs']
      for k in range(self.count()):
         tab_name = self.tabText(k)
         widget = self.widget(k)
         tab_list.append((widget, tab_name))
      return data

   def setup(self):
      pass

   def mouseMoveEvent(self, e):
      if e.buttons() != Qt.RightButton:
         return

      globalPos = self.mapToGlobal(e.pos())
      tabBar = self.tabBar()
      posInTab = tabBar.mapFromGlobal(globalPos)
      index = tabBar.tabAt(e.pos())
      tabBar.dragged_content = self.widget(index)
      tabBar.dragged_tabname = self.tabText(index)
      tabRect = tabBar.tabRect(index)

      pixmap = QPixmap(tabRect.size())
      tabBar.render(pixmap,QPoint(),QRegion(tabRect))
      mimeData = QMimeData()

      drag = QDrag(tabBar)
      drag.setMimeData(mimeData)
      drag.setPixmap(pixmap)

      cursor = QCursor(Qt.OpenHandCursor)

      drag.setHotSpot(e.pos() - posInTab)
      drag.setDragCursor(cursor.pixmap(),Qt.MoveAction)
      drag.exec_(Qt.MoveAction)

   def dragEnterEvent(self, e):
      e.accept()
      #self.parent().dragged_index = self.indexOf(self.widget(self.dragged_index))

   def dragLeaveEvent(self,e):
      e.accept()

   def dropEvent(self, e):
      if e.source().parentWidget() == self:
         return

      e.setDropAction(Qt.MoveAction)
      e.accept()
      tabBar = e.source()
      self.addTab(tabBar.dragged_content, tabBar.dragged_tabname)


if __name__ == '__main__':
   from PyQt5.QtWidgets import QWidget, QApplication, QHBoxLayout
   import sys

   class Window(QWidget):
      def __init__(self):

         super().__init__()

         self.dragged_index = None
         tabWidgetOne = TabWidget(self)
         tabWidgetTwo = TabWidget(self)
         tabWidgetOne.addTab(QWidget(), "tab1")
         tabWidgetTwo.addTab(QWidget(), "tab2")

         layout = QHBoxLayout()

         self.moveWidget = None

         layout.addWidget(tabWidgetOne)
         layout.addWidget(tabWidgetTwo)

         self.setLayout(layout)

   app = QApplication(sys.argv)
   window = Window()
   window1 = Window()
   window.show()
   window1.show()
   sys.exit(app.exec_())

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM