How can I add a “new tab” button next to the tabs of a QMdiArea in tabbed view mode?

后端 未结 5 1177
天命终不由人
天命终不由人 2020-12-05 14:46

I\'d like to have a \"new tab\" button much like Chrome or Firefox has for my QMdiArea.

I can make a button or menu item somewhere that adds a new subdo

相关标签:
5条回答
  • 2020-12-05 15:10

    I know that question is outdated, but some time ago I was looking for ready-to-use implementation of feature you requested. I digged a bit and implement this for Qt 5 -- take a look at repo.

    Main idea is to do:

    // Create button what must be placed in tabs row
    QToolButton *tb = new QToolButton();
    tb->setText("+");
    // Add empty, not enabled tab to tabWidget
    tabWidget->addTab(new QLabel("Add tabs by pressing \"+\""), QString());
    tabWidget->setTabEnabled(0, false);
    // Add tab button to current tab. Button will be enabled, but tab -- not
    tabWidget->tabBar()->setTabButton(0, QTabBar::RightSide, tb);
    
    0 讨论(0)
  • 2020-12-05 15:19

    Why not make a button out of the last tab of your QTabWidget ? Just create the last tab with a '+' symbol on it and use the currentChanged event.

    class Trace_Tabs(QTabWidget):
    
        def __init__(self):
            QTabWidget.__init__(self)       
            self._build_tabs()
    
        def _build_tabs(self):
            self.setUpdatesEnabled(True)
    
            self.insertTab(0,QWidget(), "Trace" )
            self.insertTab(1,QWidget(),'  +  ') 
    
            self.currentChanged.connect(self._add_trace) 
    
        def _add_trace(self, index):    
    
            if index == self.count()-1 :    
                '''last tab was clicked. add tab'''
                self.insertTab(index, QWidget(), "Trace %d" %(index+1)) 
                self.setCurrentIndex(index)
    
    if __name__ == '__main__':    
        app = QApplication([])    
        tabs = Trace_Tabs()
        tabs.show()    
        app.exec_()
    
    0 讨论(0)
  • 2020-12-05 15:20

    Similar concept to @Garjy's answer:

    You could use a "blank" tab and add a button to that tab. This will also replace the "close" button if you are using TabWidget.setTabsCloseable(True). It is possible to make it to the "blank" tab, so I suggest combining with @Garjy's answer or adding some text/ another new button.

    import sys
    from qtpy.QtWidgets import QTabWidget, QWidget, QToolButton, QTabBar, QApplication
    
    class Trace_Tabs(QTabWidget):
    
        def __init__(self):
            QTabWidget.__init__(self)
            self.setTabsClosable(True)
            self._build_tabs()
    
        def _build_tabs(self):
    
            self.insertTab(0, QWidget(), "Trace 0" )
    
            # create the "new tab" tab with button
            self.insertTab(1, QWidget(),'')
            nb = self.new_btn = QToolButton()
            nb.setText('+') # you could set an icon instead of text
            nb.setAutoRaise(True)
            nb.clicked.connect(self.new_tab)
            self.tabBar().setTabButton(1, QTabBar.RightSide, nb)
    
        def new_tab(self):
            index = self.count() - 1
            self.insertTab(index, QWidget(), "Trace %d" % index)
            self.setCurrentIndex(index)
    
    if __name__ == '__main__':
    
        app = QApplication(sys.argv)
    
        tabs = Trace_Tabs()
        tabs.show()
    
        app.exec_()
    
    0 讨论(0)
  • 2020-12-05 15:23

    You will have to write your own class for the QTabBar. The plus button can be added by using absolute positioning.

    I have some code here for PySide; it should give you the basic idea.

    class TabBarPlus(QtGui.QTabBar):
        """Tab bar that has a plus button floating to the right of the tabs."""
    
        plusClicked = QtCore.Signal()
    
        def __init__(self):
            super().__init__()
    
            # Plus Button
            self.plusButton = QtGui.QPushButton("+")
            self.plusButton.setParent(self)
            self.plusButton.setFixedSize(20, 20)  # Small Fixed size
            self.plusButton.clicked.connect(self.plusClicked.emit)
            self.movePlusButton() # Move to the correct location
        # end Constructor
    
        def sizeHint(self):
            """Return the size of the TabBar with increased width for the plus button."""
            sizeHint = QtGui.QTabBar.sizeHint(self) 
            width = sizeHint.width()
            height = sizeHint.height()
            return QtCore.QSize(width+25, height)
        # end tabSizeHint
    
        def resizeEvent(self, event):
            """Resize the widget and make sure the plus button is in the correct location."""
            super().resizeEvent(event)
    
            self.movePlusButton()
        # end resizeEvent
    
        def tabLayoutChange(self):
            """This virtual handler is called whenever the tab layout changes.
            If anything changes make sure the plus button is in the correct location.
            """
            super().tabLayoutChange()
    
            self.movePlusButton()
        # end tabLayoutChange
    
        def movePlusButton(self):
            """Move the plus button to the correct location."""
            # Find the width of all of the tabs
            size = sum([self.tabRect(i).width() for i in range(self.count())])
            # size = 0
            # for i in range(self.count()):
            #     size += self.tabRect(i).width()
    
            # Set the plus button location in a visible area
            h = self.geometry().top()
            w = self.width()
            if size > w: # Show just to the left of the scroll buttons
                self.plusButton.move(w-54, h)
            else:
                self.plusButton.move(size, h)
        # end movePlusButton
    # end class MyClass
    
    class CustomTabWidget(QtGui.QTabWidget):
        """Tab Widget that that can have new tabs easily added to it."""
    
        def __init__(self):
            super().__init__()
    
            # Tab Bar
            self.tab = TabBarPlus()
            self.setTabBar(self.tab)
    
            # Properties
            self.setMovable(True)
            self.setTabsClosable(True)
    
            # Signals
            self.tab.plusClicked.connect(self.addTab)
            self.tab.tabMoved.connect(self.moveTab)
            self.tabCloseRequested.connect(self.removeTab)
        # end Constructor
    # end class CustomTabWidget
    
    0 讨论(0)
  • 2020-12-05 15:26

    First, add an empty tab to your widget, and connect the currentChanged signal:

    TabsView::TabsView(QWidget *parent) :
      QWidget(parent),
      ui(new Ui::TabsView)
    {
        ui->setupUi(this);
        ui->tabWidget->clear();
        ui->tabWidget->addTab(new QLabel("+"), QString("+"));
        connect(ui->tabWidget, &QTabWidget::currentChanged, this, &TabsView::onChangeTab);
        newTab();
    }
    

    Then, on your onChangeTab slot, check if the user is clicking on the last tab, and call newTab:

    void TabsView::onChangeTab(int index)
    {
        if (index == this->ui->tabWidget->count() - 1) {
            newTab();
        }
    }
    

    Finally, on your newTab method, create the new tab and select it:

    void TabsView::newTab()
    {
        int position = ui->tabWidget->count() - 1;
        ui->tabWidget->insertTab(position, new QLabel("Your new tab here"), QString("New tab"));
        ui->tabWidget->setCurrentIndex(position);
        auto tabBar = ui->tabWidget->tabBar();
        tabBar->scroll(tabBar->width(), 0);
    }
    
    0 讨论(0)
提交回复
热议问题