Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Best practise in the implementation of QTabWidget and corner widget



  • class MyWidget(QWidget):
    
        def __init__(self, parent=None):
            super(MyWidget, self).__init__(parent)
    
            self.buttonInfo = QPushButton(self)
            self.buttonInfo.setIcon(QIcon('help-about.svg'))
            self.buttonInfo.setFlat(True)
            self.buttonInfo.clicked.connect(self.onButtonInfoClicked)
    
            self.tabs = QTabWidget()
            self.tabs.setDocumentMode(True)
            self.tabs.setMovable(True)
            self.tabs.setTabsClosable(True)
            self.tabs.setCornerWidget(self.buttonInfo)
            self.tabs.tabCloseRequested.connect(self.onButtonTabCloseClicked)
    
            layout = QVBoxLayout()
            layout.addWidget(self.tabs)
    
            self.setLayout(layout)
    
    
        ...
        def onButtonInfoClicked(self):
    
            title = QLabel()
    
            content = QWidget()
    
            button = QPushButton('Close')
            button.setShortcut(QKeySequence.Cancel)
            button.clicked.connect(self.onButtonInfoCloseClicked)
    
            layout = QVBoxLayout()
            layout.addWidget(title)
            layout.addWidget(content)
            layout.addWidget(button)
    
            self.page = QWidget()
            self.page.setLayout(layout)
    
            self.layout().removeWidget(self.tabs)
            self.tabs.setParent(None)
            self.layout().addWidget(self.page)
    
    
        def onButtonInfoCloseClicked(self):
    
            self.layout().removeWidget(self.page)
            self.page.setParent(None)
            self.layout().addWidget(self.tabs)
    
    1. What is the best practise in the implementation of QTabWidget and corner widget?
      It works, but is it the best solution?

    2. And how can I implement the shortcut without button to close the page?

    Thanks



  • #2 is fixed:

    shortcut = QShortcut(QKeySequence.Cancel, self.page)
    shortcut.activated.connect(self.onButtonInfoCloseClicked)
    

  • Qt Champions 2019

    @NonNT said in Best practise in the implementation of QTabWidget and corner widget:

    corner widget

    What do you mean by this?



  • @jsulm
    A widget shown in the corner of the tab widget.
    https://doc.qt.io/qt-5/qtabwidget.html#cornerWidget

    To display the page instead of the tabs widget, I'm just doing the following:

    1. remove tabs widget from the layout
    2. unparent tabs widget
    3. add page widget to the layout

    and vice versa to display the tabs widget again.

    But it is the best solution?


  • Banned

    @jsulm if you looked at his code you would see the answer to that question -- QTabWidget.setCornerWidget( )

    @NonNT first you did not include your subsequent fix into your original code nor did you indicate where you inserted it so I do not have that included in this rendition. Next I am not sure how you got your code to work or you did not include enough code to provide an MRE (Minimally Reproducible Example) that could be copy/paste/run -- to facilitate getting an answer to your issue as such I had to add several elements -- which may not be inline with what you did to create a MUC (Minimal Usable Code) that I could render to test out your code.

    from PyQt5.QtCore    import *
    from PyQt5.QtGui     import *
    from PyQt5.QtWidgets import *
    
    from sys import exit as sysExit
    
    class MyTab(QWidget):
        def __init__(self, Index):
            QWidget.__init__(self)
            
            self.lblTab = QLabel('I am a Tab ' + str(Index))
            
            VBox = QVBoxLayout()
            VBox.addStretch(1)
            VBox.addWidget(self.lblTab)
            VBox.addStretch(1)
            
            self.setLayout(VBox)
    
    class MyWidget(QWidget):
        def __init__(self):
    # This wrong because unless you need super( ) for the issue items
    # was created to solve you should not use it as it creates more
    # issues than it resolves if you are not using it for that purpose
    #        super(MyWidget, self).__init__(parent)
    # Also sending the parent on to the QWidget is completely unnecessary
    # as the QWidget will do nothing with it at all -- thus if you are 
    # not going to be using parent within your Class then do not bother
    # receiving it -- aka remove  ", parent=None"  above
            QWidget.__init__(self)
    
    # If you want to reference this as a property of the Class it must be
    # defined within the __init__ method of the Class
            self.page = QWidget()
    
            self.btnInfo = QPushButton(self)
            self.btnInfo.setIcon(QIcon('./images/grn-hov-16.png'))
            self.btnInfo.setFlat(True)
            self.btnInfo.clicked.connect(self.OnInfoClicked)
    
            self.tabs = QTabWidget()
    
            self.tabs.setDocumentMode(True)
            self.tabs.setMovable(True)
            self.tabs.setTabsClosable(True)
            self.tabs.setCornerWidget(self.btnInfo)
            self.tabs.tabCloseRequested.connect(self.OnTabClose)
    # You kind of need to Add a Tab to the Widget in order for the Tab Widget to display something
            self.tabs.addTab(MyTab(1), 'Tab 1')
    
            layout = QVBoxLayout()
            layout.addWidget(self.tabs)
    
            self.setLayout(layout)
    
        def OnInfoClicked(self):
            title = QLabel()
    
            content = QWidget()
    
            button = QPushButton('Open Tab')
            button.setShortcut(QKeySequence.Cancel)
            button.clicked.connect(self.OnTabClose)
    
            layout = QVBoxLayout()
            layout.addWidget(title)
            layout.addWidget(content)
            layout.addWidget(button)
    
            self.page = QWidget()
            self.page.setLayout(layout)
    
            self.layout().removeWidget(self.tabs)
            self.tabs.setParent(None)
            self.layout().addWidget(self.page)
    
        def OnTabClose(self):
            self.layout().removeWidget(self.page)
            self.page.setParent(None)
            self.layout().addWidget(self.tabs)
            
    if __name__ == "__main__":
        MainEventThred = QApplication([])
    
        MainApp = MyWidget()
        MainApp.show()
    
        MainEventThred.exec()
    
      # If anyone wants more extensive free help I run an online lab-like classroom-like 
      # message server feel free and drop by you will not be able to post until I clear 
      # you as a student as this prevents spammers so if interested here is the invite
      # https://discord.gg/3D8huKC
    

    I also noticed that before adding in the Corner Widget (due to it not being fully functional) the Close functionality of the Tab seemed to work just fine -- granted another Tab was not auto-created

    Also I changed the message in your button to reflect what it is actually doing within the code and changed the button Icon to something I had -- still I would think that yours should be ./help-about.svg as that would indictate the icon is in the same directory


Log in to reply