1

In my application windows all have a QDialog context menu for settings etc, accessible with a right mouse click. In one of these dialog boxes we want to display a popup (QMessageBox) warning the user of an action, but Qt only allows on dialog box at once, when a new one is opened the current one is hidden. They are also hidden when they loose focus etc which is functionality I need to maintain.

I've been looking at event filters, which I can use to capture a Hide event but I can't seem to block the hide from actually taking place. Either combination of returning true or setting accept on the event doesn't seem to have any effect.

bool windowSettings::eventFilter(QObject *object, QEvent *event)
{
    if (object == this && event->type() == QEvent::Hide) {
        QHideEvent *hideEvent = static_cast<QHideEvent *>(event);
        hideEvent->accept();    //Should tell further event calls it has already been dealt with
        return true;    //Should indicate event has been dealt with

    }
    return false;
}

The context menu is actuall a custom implementation of QDialog (lets call it myQDialog). So I tried overriding the hide() function there and adding bool preventHiding which was used in the new hide function to determine if the dialog should actually be hidden. Calling hide(); directly results in in the overeidden function being called, but showing the confirmation box or clicking outside the dialog box still triggers the hide event but not the overridden function. (I tried this with and without the event filter being present in the code).

Instead I have overridden setVisible() which is called from show/hide. This gets called consistently and my implementation below stops the dialog from closing, but I can't click on the message box despite it still being shown over the top of the original dialog.

void myQDialog::setVisible(bool visible)
{
    if(preventHide)
    {
        //Don't hide
    }
    else
    {
        QDialog::setVisible(visible);
    }
}

Is there a way to either capture and stop the hide even, or keep showing the original dialog while still being able to interact with the message box it creates?

MikeS159
  • 1,884
  • 3
  • 29
  • 54
  • I think the elephant in the room is: why is your context menu inherited from QDialog? Only one QDialog at a screen is a feature of that class. Why do you need QDialog for your context menu specifically? I would strongly urge you to consider changing that. – MarPan Feb 26 '20 at 11:08
  • Unfortunately this is the current implementation, changing it would be a huge undertaking (and not something I would do because of the possible regressions). The priority with any UI changes is to minimize and differences the user experiences. – MikeS159 Feb 26 '20 at 11:23

2 Answers2

1

You can just make your message box a popup, it's easy!

When you create your message box, give it a Window Flag as below:

msgBox.setWindowFlags(Qt::WindowType::Popup);

This will mean it won't have any effect on the window behind.

The docs can be found here

GPPK
  • 6,546
  • 4
  • 32
  • 57
  • `QMessageBox` done that way looks differently (didn't have title/decorations in my case) and still closes a dialog in my case. – z33k Apr 09 '20 at 14:25
0

Maybe you can look at this part WindowModality that seems to allow you to manage input in different windows(dialogs)

Marco Medri
  • 176
  • 3