QWidget is displaying behind the canvas (but in front of all other dockers), how to avoid it, please?

I have a QWidget with QMainWindow (krita qwin) as its parent.

The pie menu displays over everything just fine as you can see below:

The problem is that after I click on any tab of any docker (for example Tool Options, Advanced Color Selector, …) to switch to it something changes and now the menu displays only over dockers and not canvas which is a problem for me :slight_smile: as you can see below:

I can keep the widget’s parent clear and set it as a transparent window over Krita but that brings different issues, in this branch (GitHub - viksl/kritapluginpiemenu at GUISettings) I’m trying to have the menu look more like part of krita rather than a separate window (which can cause some troubles when it opens with focus, …) other than the issues described in this post I managed to get everything working just fine but I can’t figure out what to do about this if there’s anything I can do at all?

I’d really appreciate help in this matter.

Normally Qt parents don’t want to define top child among children, and editing children list order is BIG no no.
So it would best to keep pie popup menu as pie popup window that is parented to main window.

It’s really normal to create floating windows a top of parent widget, just to get correct z-order (QComboBox, QMenu, QToolTip …). And note that child widgets that don’t have own window are always cropped to parent widgets window, resizing of main window at border areas just so that popup menu can draw it self without cropping, or use off-center origin in pie menu?

There are some issues on how to create transparent window on all platforms, but it should be easier than trying to define exact draw z-order of all children of main window.

Maybe this gives some new ideas?

from PyQt5.QtCore import (
        Qt,
        QPoint)

from PyQt5.QtGui import (
        QKeySequence,
        QCursor,
        QRegion)

from PyQt5.QtWidgets import (
        QWidget,
        QPushButton,
        QShortcut,
        QVBoxLayout)

class PieMenu(QWidget):
    """
    Or inherit QMenu ?
    override layout of child QToolButtons (one for each QAction in menu)
    QMenu.exec_() would show window in modal state at given position.
    """

    def __init__(self, parent=None):
        super().__init__(parent, Qt.Popup | Qt.NoDropShadowWindowHint | Qt.FramelessWindowHint)
        self.setAttribute(Qt.WA_TranslucentBackground, True)
        self.setFocusPolicy(Qt.NoFocus)
        self.setAutoFillBackground(False)  # just to be sure
        # self.setMask(self.create_mask_from_buttons())
        self.setObjectName('pie_menu')
        self.create_ui()

    def create_mask_from_buttons(self):
        """
        Create mask from buttons, so that gaps in
        between buttons are transparent to inputs.

        ToDo: implement...
        """
        return QRegion()

    def create_ui(self):
        layout = QVBoxLayout()
        self.setLayout(layout)
        for i in range(12):
            button = QPushButton(f'button_{i}', parent=self)
            layout.addWidget(button)

    def popup(self):
        cursor_pos = QCursor.pos()
        half_size = 0.5 * self.size()
        offset = QPoint(half_size.width(), half_size.height())
        self.move(cursor_pos - offset)
        # ToDo: override, override cursor?
        # old_override = QGuiApplication.overrideCursor()
        # if old_override...
        #     QGuiApplication.changeOverrideCursor()
        self.show()
        # or show as modal widget?
        # self.setWindowModality(Qt.ApplicationModal)

window = Application.activeWindow()
qwindow = window.qwindow()
key_sq = QKeySequence(Qt.CTRL + Qt.Key_Space)

for c in list(qwindow.children()):
    if isinstance(c, QShortcut) and (c.key() == key_sq):
        print('Easy testing... removeing clashing shortcut...')
        c.deleteLater()

pie_menu = PieMenu(parent=qwindow)
shortcut = QShortcut(key_sq, qwindow, pie_menu.popup)

/AkiR

Thanks, I’ll check it out if it solves my issues :slight_smile: