Suresh Kumar
Suresh Kumar

Reputation: 33

Aligning popup widget in PyQt5

I've seen a number of replies on SO regarding this matter but not specifically to QMenu and QToolButton. Would appreciate some pointers on aligning the popup widget to the right side of the button. Here's a basic code I'm working off..

import sys
from PyQt5.QtWidgets import *


class test(QWidget):
    def __init__(self):
        super().__init__()
        self.resize(200, 100)
        layout = QHBoxLayout(self)
        label = QLabel('Testing QToolButton Popup')
        toolbutton = QToolButton()
        toolbutton.setPopupMode(QToolButton.InstantPopup)

        widget = QWidget()
        widgetLayout = QHBoxLayout(widget)
        widgetLabel = QLabel('Popup Text')
        widgetSpinbox = QSpinBox()
        widgetLayout.addWidget(widgetLabel)
        widgetLayout.addWidget(widgetSpinbox)

        widgetAction = QWidgetAction(toolbutton)
        widgetAction.setDefaultWidget(widget)

        widgetMenu = QMenu(toolbutton)
        widgetMenu.addAction(widgetAction)
        toolbutton.setMenu(widgetMenu)

        layout.addWidget(label)
        layout.addWidget(toolbutton)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = test()
    win.show()
    sys.exit(app.exec_())

The outcome looks like this:

popup image

Upvotes: 1

Views: 698

Answers (1)

eyllanesc
eyllanesc

Reputation: 244282

The Qt developer thought the default position was correct, so if you want to modify the alignment you must move the QMenu as I show below:

import sys
from PyQt5.QtCore import QPoint
from PyQt5.QtWidgets import (
    QApplication,
    QHBoxLayout,
    QLabel,
    QMenu,
    QSpinBox,
    QToolButton,
    QWidgetAction,
    QWidget,
)


class Menu(QMenu):
    def showEvent(self, event):
        if self.isVisible():
            button = self.parentWidget()
            if button is not None:
                pos = button.mapToGlobal(button.rect().bottomRight())
                self.move(pos - self.rect().topRight())
        super().showEvent(event)


class Test(QWidget):
    def __init__(self):
        super().__init__()
        self.resize(200, 100)
        layout = QHBoxLayout(self)
        label = QLabel("Testing QToolButton Popup")
        toolbutton = QToolButton(popupMode=QToolButton.InstantPopup)

        widgetLabel = QLabel("Popup Text")
        widgetSpinbox = QSpinBox()

        widget = QWidget()
        widgetLayout = QHBoxLayout(widget)
        widgetLayout.addWidget(widgetLabel)
        widgetLayout.addWidget(widgetSpinbox)

        widgetAction = QWidgetAction(toolbutton)
        widgetAction.setDefaultWidget(widget)

        widgetMenu = Menu(toolbutton)
        widgetMenu.addAction(widgetAction)
        toolbutton.setMenu(widgetMenu)

        layout.addWidget(label)
        layout.addWidget(toolbutton)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = Test()
    win.show()
    sys.exit(app.exec_())

Upvotes: 2

Related Questions