#python #pyqt5
#python #pyqt5
Вопрос:
главное окно с панелью меню, панелью инструментов и строкой состояния
class TajirMWindow(QMainWindow):
"""Main Window."""
def __init__(self, parent=None):
"""Initializer."""
super().__init__(parent)
self.setWindowTitle("Tajir/Home")
self.resize(800, 400)
self.centralWidget = QLabel("Hello, World")
self.centralWidget.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
self.setCentralWidget(self.centralWidget)
self._createActions()
self._connectActions()
self._createMenuBar() #Menus
self._createToolBars()#tools
'''
Menu Bar function
'''
def _createMenuBar():
menuBar = self.menuBar()
fileMenu = menuBar.addMenu("amp;File")
outilMenu = menuBar.addMenu("amp;Outils")
menuBar.addSeparator()
achatMenu = menuBar.addMenu("Bying")
stockMenu = menuBar.addMenu("Stocks")
menuBar.addSeparator()
helpMenu = menuBar.addMenu("amp;Help")
когда я запускаю код, никаких проблем не возникает, но я не получил разделитель
Комментарии:
1. Вы обеспечили правильное написание «строки меню»? У вас есть две опечатки с ‘menuBap’, чтобы убедиться, что это не проблема 😉
2. ошибка только здесь, в вопросе / мой код правильный MenuBar.addSeparator()
3. QMenuBar не поддерживает разделители.
4. Просто чтобы убедиться, вам нужны вертикальные разделители в самой панели меню, а не горизонтальные разделители в меню панели меню…. Я ошибся, и благодаря musicamente понял это сейчас — удалил мой ответ.
5. @hamzachenni когда вы публикуете / редактируете свой код, пожалуйста, убедитесь, что его синтаксис правильный: например, в
_createMenuBar()
функции отсутствуетself
аргумент, а другие функции, подобные_createActions()
этому, отсутствуют в вашем коде (и не имеют отношения к примеру, поэтому этих строк там быть не должно).
Ответ №1:
QMenuBar изначально не поддерживает разделители. Он даже не поддерживает добавление QWidgetActions, поскольку они отображаются как пустые действия, а их виджет фактически никогда не отображается.
Единственное решение — создать «поддельное» действие с уникальным идентификатором и обойти рисование действия с помощью QProxyStyle: мы переопределяем, sizeFromContents()
чтобы, когда QMenuBar вычисляет размеры своих действий, он возвращал соответствующую ширину, и drawControl()
рисовать поддельный QFrame, который отображается в виде VLine (напримервертикальные разделители в конструкторах).
Важно: это не будет работать на macOS при использовании nativeMenuBar.
class MenuProxy(QtWidgets.QProxyStyle):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# create a fake frame that we'll use as a source for the separator
self.fakeFrame = QtWidgets.QFrame(frameShape=QtWidgets.QFrame.VLine)
def sizeFromContents(self, content, opt, size, widget=None):
size = super().sizeFromContents(content, opt, size, widget)
if (content == self.CT_MenuBarItem and
isinstance(widget, QtWidgets.QMenuBar)
and opt.text == '_'):
# use the size hint of the frame to return the correct width
size.setWidth(self.fakeFrame.sizeHint().width())
return size
def drawControl(self, ctl, opt, qp, widget=None):
if (ctl == self.CE_MenuBarItem and
isinstance(widget, QtWidgets.QMenuBar) and
opt.text == '_'):
self.fakeFrame.resize(opt.rect.size())
frameOpt = QtWidgets.QStyleOptionFrame()
self.fakeFrame.initStyleOption(frameOpt)
# the frame will be drawn using its own coordinates (starting
# from 0, 0), so we need to save the current state of the painter
# and then translate to the correct position
qp.save()
qp.translate(opt.rect.topLeft())
# paint the "fake" frame
self.drawControl(self.CE_ShapedFrame, frameOpt, qp, self.fakeFrame)
# restore the painter to the previous position
qp.restore()
return
super().drawControl(ctl, opt, qp, widget)
class YourWindow(QtWidgets.QMainWindow):
def __init__(self):
# ...
sep = QtWidgets.QAction('_', self, enabled=False)
menuBar.addAction(sep)
# ...
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
app.setStyle(MenuProxy())
Обратите внимание, что:
- поскольку QMenuBar автоматически игнорирует действия разделителя,
setSeparator(True)
его нельзя использовать для действия разделителя; - действие «разделитель» должно быть отключено, иначе навигация с клавиатуры попытается сфокусировать его;
- это будет работать даже для строк меню, созданных в Designer, если вы добавите меню с именем с уникальным идентификатором (меню должно быть отключено, как описано в предыдущем пункте);
- символ
'_'
подчеркивания используется для идентификации разделителей в стиле, поскольку QStyle не имеет прямого доступа к действиям (поэтому мы не можем использоватьaction.setData
), и требуется использование специального символа, потому что некоторые стили Qt имеют плохую привычку устанавливать мнемонику (подчеркнутые буквы, которые используются в качестве ярлыков) путем изменения текста /метка тоже, поэтому, если вы используете что-то вроде «separator», она может стать «amp; separator» или даже «s amp; eparator», если у другого объекта уже есть ярлык «s» или вы добавляете больше разделителей. Другая возможность — использовать ‘amp;’ или ‘amp;amp;amp;’ или любой другой уникальный не буквенно-цифровой идентификатор символа, например'_#'
.