Close the widget window by clicking outside

This is a kind of chicken and egg problem. I want the window of my widget to close when the mouse clicks on it. As far as I understand, for my widget there will be no mouse events for a click occurring outside of it. There is a SetFocus slot, but where is its counter-counter or loss of focus? "focusOutEvent" is not called for my class.

My widget window is a child window of the widget that always appears in my main window, and this is "Qt :: ToolTip", so I assume that some problems may arise from this fact. Anyway this?

My goal: I have my own toolbar widget on which the buttons on it can have drop-down widgets. These drop-down widgets do not have a standard window. I don’t want them to “steal” the focus header from the main window, and I want them to disappear as soon as the user clicks “ANYWHERE” on the screen outside their region. I have serious difficulties finding a strategy that does not jeopardize Qt to do this.

Am I missing something? (bid me).

+7
source share
4 answers

I used:

setWindowFlags(Qt::FramelessWindowHint | Qt::Popup); 

This works well on OSX and Windows. My window displays correctly, does not steal focus from the main window title, and the focus loss event is called correctly as soon as I click it.

+13
source

If your widget could focus and “steal” the focus on some other widgets, it would be easier. Something like this might work:

 class ToolBarWidget : public QWidget { Q_OBJECT public: explicit ToolBarWidget(QWidget * parent = 0) { setFocusPolicy(Qt::ClickFocus); } protected: void focusOutEvent(QFocusEvent * event) { close(); } } 

And when creating any of your widgets, you would do:

 ToolBarWidget * pWidget = new ToolBarWidget(this); pWidget->show(); pWidget->setFocus(); 

Done! Well, I think, not quiet. Firstly, you do not want the ToolBarWidget to get any focus in the first place. And secondly, you want the user to be able to click anywhere and ToolBarWidget to be hidden. This way you can track every created ToolBarWidget. For example, in the member variable QList ttWidgets. Then, whenever you create a new ToolBarWidget, you must do this:

 ToolBarWidget * pWidget = new ToolBarWidget(this); pWidget->installEventFilter(this); pWidget->show(); 

and in your main widget class, implement the eventFilter () function. Something like:

 bool MainWidget::eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::FocusOut || event->type() == QEvent::KeyPress || event->type() == QEvent::MouseButtonPress) { while (!ttWidgets.isEmpty()) { ToolBarWidget * p = ttWidgets->takeFirst(); p->close(); p->deleteLater(); } } return MainWidget::eventFilter(obj, event); } 

And it will work. Because this way, even if your ToolTabWidgets do not get focus, some other widgets in your main widget have focus. And as soon as this changes (whether the user is called from your window or on another control inside it, or in this case a key or mouse button is pressed, the control will reach this eventFilter () function and close all your tab widgets.

BTW to capture MouseButtonPress, KeyPress, etc. from other widgets, you need to either install InstallEventFilter on them, or simply override the QWidget :: event (QEvent *) function in the main widgets and look for those events there.

+6
source

you can do it using QDesktopWidget.h like this

 void MainWindow::on_actionAbout_triggered() { AboutDialog aboutDialog; //Set location of player in center of display aboutDialog.move(QApplication::desktop()->screen()->rect().center() -aboutDialog.rect().center()); // Adding popup flags so that dialog closes when it losses focus aboutDialog.setWindowFlags(Qt::Popup); //finally opening dialog aboutDialog.exec(); } 
+1
source

Here's what worked for me so as not to distract from the main application:

.hour

 bool eventFilter(QObject *obj, QEvent *event) override; 

.cpp

 bool Notification::eventFilter(QObject *obj, QEvent *event) { if(event->type() == QEvent::MouseButtonPress) deleteLater(); return QObject::eventFilter(obj, event); } ... // somewhere else (ie constructor, main window,...) qApp->installEventFilter(this); 
0
source

All Articles