这是一种鸡和蛋的问题。当鼠标点击外面时,我想关闭我的小部件窗口。据我了解,我的小部件没有鼠标事件,因为在它之外发生了点击。有一个SetFocus插槽,但其对应或焦点丢失在哪里?我没有为我的班级调用“focusOutEvent”。
我的窗口小部件窗口是一个窗口小部件的子窗口,它总是显示在我的主窗口上,它是一个“Qt :: ToolTip”,因此我假设可能会出现一些问题。任何方式?
我的目标:我有一个自定义工具栏小部件,其上的按钮可能有“下拉”小部件。这些下拉小部件没有标准的窗口框架。我不希望他们从主窗口“窃取”字幕焦点,我希望他们一旦用户点击他们所在地区以外的屏幕上的ANYWHERE就会消失。我很难找到一个在Qt上没有妥协的策略来完成这项工作。
我错过了什么吗? (打赌我)。
答案 0 :(得分:15)
我用过:
setWindowFlags(Qt::FramelessWindowHint | Qt::Popup);
这似乎在OSX和Windows上运行良好。我的窗口显示正确,不从主窗口的标题中窃取焦点,并且只要我点击它外面就会正确调用焦点丢失事件。
答案 1 :(得分:7)
如果您的小部件可能具有焦点,并且“窃取”某些其他小部件的标题焦点,那么它会更容易。这样的事情可以奏效:
class ToolBarWidget : public QWidget
{
Q_OBJECT
public:
explicit ToolBarWidget(QWidget * parent = 0)
{
setFocusPolicy(Qt::ClickFocus);
}
protected:
void focusOutEvent(QFocusEvent * event)
{
close();
}
}
当你创建任何小工具时,你会这样做:
ToolBarWidget * pWidget = new ToolBarWidget(this);
pWidget->show();
pWidget->setFocus();
完成!好吧,我想不安静。首先,您不希望ToolBarWidget首先获得任何焦点。其次,您希望用户能够在任何地方单击并隐藏ToolBarWidget。 因此,您可以跟踪您创建的每个ToolBarWidget。例如,在'QList ttWidgets'成员变量中。然后,每当你创建一个新的ToolBarWidget时,你都会这样做:
ToolBarWidget * pWidget = new ToolBarWidget(this);
pWidget->installEventFilter(this);
pWidget->show();
在主窗口小部件类中,实现eventFilter()函数。类似的东西:
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);
}
这将有效。因为这样,即使您的ToolTabWidgets没有获得焦点,主窗口小部件中的其他窗口小部件也会有焦点。一旦改变(无论用户是否从窗口中,或在其中的另一个控件上,或者在这种情况下,按下按键或鼠标按钮,控件将到达该eventFilter()函数并关闭所有选项卡小部件。
顺便说一下,为了从其他小部件中捕获MouseButtonPress,KeyPress等,你需要在它们上面安装EventEvent,或者只是在你的主小部件中重新实现QWidget :: event(QEvent * event)函数,在那里寻找那些活动。答案 2 :(得分:1)
你可以像这样使用QDesktopWidget.h
来做到这一点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();
}
答案 3 :(得分:0)
这是我的工作,目的是不使主要应用程序失去重点:
.h
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 (i.e. constructor, main window,...)
qApp->installEventFilter(this);
答案 4 :(得分:0)
OP 自己的答案对于 4.8 以下的 Qt 版本非常有用,但正如他们在答案中提到的那样,它不适用于高于 4.8 的版本。 Qt::Popup 小部件在小部件外部点击鼠标时不会消失,它会接收所有通常会关闭它的输入。
经过进一步调查,这只是非对话框小部件的问题。当用户在其外部单击时,使用 Qt::Popup 的 QDialog 将正确关闭,但任何其他 QWidget,如 QFrame,则不会。因此,为了解决 Qt 4.8 中的这种行为变化,所需要做的就是将小部件包装在 QDialog 中。