PyQt5: setParent на QPushButton не добавляет его к родителю - PullRequest
0 голосов
/ 24 апреля 2020

Что касается этого ответа о добавлении кнопки новой вкладки в QTabWidget, я не уверен, где QPushButton добавлен в QTabBar. Я предполагаю, что метод setParent на pushButton добавляет его на панель вкладок. Но когда я пытаюсь это реализовать, pushButton, кажется, нигде не появляется на панели вкладок, даже если я добавляю жесткие значения к операции перемещения.

Вот минимальный воспроизводимый пример,

from PyQt5 import QtGui, QtCore, QtWidgets
class TabBarPlus(QtWidgets.QTabBar):
    """Tab bar that has a plus button floating to the right of the tabs."""

    plusClicked = QtCore.pyqtSignal()

    def __init__(self):
        super().__init__()

        # Plus Button
        self.plusButton = QtWidgets.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 = QtWidgets.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(QtWidgets.QTabWidget):
    """Tab Widget that that can have new tabs easily added to it."""

    def __init__(self, parent=None):
        super().__init__(parent)

        # 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
class AppDemo(QtWidgets.QMainWindow):
    def __init__(self):
        super(AppDemo, self).__init__()
        self.centralwidget = QtWidgets.QWidget(self)
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
        self.horizontalLayout.setContentsMargins(0, -1, 0, -1)

        self.playlist_manager = CustomTabWidget(self.centralwidget)

        self.horizontalLayout.addWidget(self.playlist_manager)

        blankWidget = QtWidgets.QWidget(self.playlist_manager)
        self.playlist_manager.addTab(blankWidget, "New")
        self.setCentralWidget(self.centralwidget)

        self.show()
# end class AppDemo


def main():
    import sys
    app = QtWidgets.QApplication(sys.argv)

    w = AppDemo()
    w.setWindowTitle('AppDemo')
    w.show()

    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

Ожидается, что кнопка «+» появится справа от всех вкладок, но такая кнопка не отображается.

1 Ответ

0 голосов
/ 25 апреля 2020

Хорошо, после некоторого мозгового штурма я разобрался в проблеме. В отличие от PyQt4. Ширина QTabBar не охватывает всю ширину QTabWidget, и поэтому PlusButton при перемещении вправо от всех вкладок будет превышать ширину родительского виджета и исчезнет.

Решение этого состоит в том, чтобы добавьте QPushButton в сам QTabWidget и создайте разметку из QTabBar.

Вот рабочий пример, я изменил значения, чтобы соответствовать моему сценарию использования

class tabBarPlus(QTabBar):
    layoutChanged = pyqtSignal()
    def resizeEvent(self, event):
        super().resizeEvent(event)
        self.layoutChanged.emit()

    def tabLayoutChange(self):
        super().tabLayoutChange()
        self.layoutChanged.emit()


class customTabWidget(QTabWidget):
    plusClicked = pyqtSignal()
    def __init__(self, parent=None):
        super(customTabWidget, self).__init__(parent)

        self.tab = tabBarPlus()
        self.setTabBar(self.tab)

        self.plusButton = QPushButton('+', self)
        self.plusButton.setFixedSize(35, 25)
        self.plusButton.clicked.connect(self.plusClicked.emit)
        self.setMovable(True)
        self.setTabsClosable(True)

        self.tab.layoutChanged.connect(self.movePlusButton)

    def movePlusButton(self):
        size = sum([self.tab.tabRect(i).width() for i in range(self.tab.count())])
        h = max(self.tab.geometry().bottom() - 24, 0)
        w = self.tab.width()
        print(size, w, h)
        if size > w:
            self.plusButton.move(w-self.plusButton.width(), h)
        else:
            self.plusButton.move(size-2, h)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...