Как выровнять элемент QToolButton внутри QToolBar?

Рейтинг: 1Ответов: 1Опубликовано: 08.06.2023

Я создал следующий тулбар, внутри которого поместил различные экшены и один QToolButton, который служит в качестве раскрывающегося меню, за счет InstantPopup (до этого делал QMenu.
Но там мне очень не нравилась стрелка справа, которая раскрывала это меню.
Из-за нее элемент был не центрирован, потому что стрелка тоже занимала дополнительное место по ширине).

Я подумал, что QToolButton решит проблему, так как там нет этой боковой стрелки, но не тут то было, теперь элемент просто смещен влево без какой либо на то причины (подразумеваю, что эта стрелка просто невидима, но место она также занимает).

Вот непосредственно класс тулбара, логотип и главное окно:

import sys

from PyQt6.QtSvgWidgets import QSvgWidget
from PyQt6.QtWidgets import QApplication, QMainWindow, QProgressBar, QVBoxLayout, QHBoxLayout, QWidget, QPushButton, \
    QLabel, QToolBar, QToolButton
from PyQt6.QtCore import QRect, QSize, Qt, QXmlStreamReader
from PyQt6.QtGui import QIcon, QPixmap, QFont, QAction, QPainter
from PyQt6.QtSvg import QSvgRenderer


class SvgLogo(QSvgWidget):
    def __init__(self):
        super().__init__()
        self.text = open('logo_without_text.svg', 'r')
        self.svg_render = QSvgRenderer(QXmlStreamReader(self.text.read()))

    def paintEvent(self, event) -> None:
        qp = QPainter(self)
        self.svg_render.render(qp)


class ToolBar(QToolBar):
    def __init__(self):
        super().__init__()

        self.setObjectName('toolbar')
        self.setStyleSheet("#toolbar {spacing: 5px;}")
        self.setIconSize(QSize(32, 32))
        self.setMovable(False)

        self.logo = SvgLogo()
        self.logo.setFixedSize(QSize(60, 50))
        self.addWidget(self.logo)
        self.addSeparator()

        self.add_profile_action = QAction('Создать профиль')
        self.add_profile_action.setIcon(QIcon('img/add_prof.png'))
        self.addAction(self.add_profile_action)

        self.delete_profile_action = QAction('Удаление профилей')
        self.delete_profile_action.setIcon(QIcon('img/delete_prof.png'))
        self.addAction(self.delete_profile_action)

        self.export_configs_action = QAction('Сохранить конфигурацию Ctrl+S')
        self.export_configs_action.setShortcut('Ctrl+S')
        self.export_configs_action.setIcon(QIcon('img/save_conf.png'))
        self.addAction(self.export_configs_action)
        
        # вот то самое раскрывающееся меню:
        self.profiles_menu = QToolButton()
        self.profiles_menu.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup)
        self.profiles_menu.setObjectName('profilesMenu')
        self.profiles_menu.setIcon(QIcon('img/profiles_set.png'))
        self.addWidget(self.profiles_menu)

        self.exit_action = QAction('Выход Ctrl+Q', self)
        self.exit_action.setShortcut('Ctrl+Q')
        self.exit_action.setIcon(QIcon('img/exit_app.png'))
        self.addAction(self.exit_action)


class MainWindow(QMainWindow):
    smooth = False

    def __init__(self):
        super().__init__()
        self.setIconSize(QSize(32, 32))

        self.central = QWidget()
        self.central.setObjectName('centralWidget')
        self.setCentralWidget(self.central)

        # боковая панель
        self.toolbar = ToolBar()
        self.addToolBar(Qt.ToolBarArea.LeftToolBarArea, self.toolbar)


app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()

Основная проблема так и не решилась, элемент с иконкой шестеренки выглядит все также странно:

Куда ее клонит?


Я вообще, если честно, слабо понимаю принципы размещения на тулбаре.
Может быть есть какие то способы управления этим вручную?
Или быть может нужно как-то по другому добавлять элементы?

Ответы

▲ 1Принят

Как вариант:

import sys

#      установите свои импорты
'''                                          
from PyQt6.QtSvgWidgets import QSvgWidget
from PyQt6.QtWidgets import QApplication, QMainWindow, QProgressBar, QVBoxLayout, QHBoxLayout, QWidget, QPushButton, \
    QLabel, QToolBar, QToolButton
from PyQt6.QtCore import QRect, QSize, Qt, QXmlStreamReader
from PyQt6.QtGui import QIcon, QPixmap, QFont, QAction, QPainter
from PyQt6.QtSvg import QSvgRenderer
'''
from PyQt5.Qt import *


class SvgLogo(QSvgWidget):
    def __init__(self):
        super().__init__()
# установите свое ------> vvvvvvvvvvvvvvvvv        и в других местах
        self.text = open('radio_checked.svg', 'r')
        self.svg_render = QSvgRenderer(QXmlStreamReader(self.text.read()))

    def paintEvent(self, event) -> None:
        qp = QPainter(self)
        self.svg_render.render(qp)


class ToolBar(QToolBar):
    def __init__(self):
        super().__init__()

        self.setObjectName('toolbar')
        self.setStyleSheet("#toolbar {spacing: 5px; background-color: #D98C00;}")
        self.setIconSize(QSize(32, 32))
        self.setMovable(False)

        self.logo = SvgLogo()
        self.logo.setFixedSize(QSize(60, 50))
        self.addWidget(self.logo)
        self.addSeparator()

        self.add_profile_action = QAction('Создать профиль')
        self.add_profile_action.setIcon(QIcon('im.png'))
        self.addAction(self.add_profile_action)

        self.delete_profile_action = QAction('Удаление профилей')
        self.delete_profile_action.setIcon(QIcon('Ok.png'))
        self.addAction(self.delete_profile_action)

        self.export_configs_action = QAction('Сохранить конфигурацию Ctrl+S')
        self.export_configs_action.setShortcut('Ctrl+S')
        self.export_configs_action.setIcon(QIcon('im.png'))
        self.addAction(self.export_configs_action)
        
# вот то самое раскрывающееся меню:
        widget = QWidget()                                            # +++
        hlay = QHBoxLayout(widget)                                    # +++
        hlay.setContentsMargins(0, 0, 0, 0)                           # +++
        
        self.profiles_menu = QToolButton()
        self.profiles_menu.setPopupMode(
            QToolButton.ToolButtonPopupMode.InstantPopup)
        self.profiles_menu.setObjectName('profilesMenu')

#        self.profiles_menu.setIcon(QIcon('im.png'))
        self.profiles_menu.setIconSize(QSize(32, 32))                 # +++
        self.profiles_menu.setAutoRaise(True)                         # +++
        self.profiles_menu.setIcon(                                   # +++
            QApplication.style().standardIcon(QStyle.SP_TitleBarCloseButton)) 
        
        hlay.addWidget(self.profiles_menu)

#        self.addWidget(self.profiles_menu)                           # ---
        self.addWidget(widget)                                        # +++

        self.exit_action = QAction('Выход Ctrl+Q', self)
        self.exit_action.setShortcut('Ctrl+Q')
        self.exit_action.setIcon(QIcon('Ok.png'))
        self.addAction(self.exit_action)


class MainWindow(QMainWindow):
    smooth = False

    def __init__(self):
        super().__init__()
        self.setIconSize(QSize(32, 32))

        self.central = QWidget()
        self.central.setObjectName('centralWidget')
        self.setCentralWidget(self.central)

        # боковая панель
        self.toolbar = ToolBar()
        self.addToolBar(Qt.ToolBarArea.LeftToolBarArea, self.toolbar)


app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()

введите сюда описание изображения