这有点鸡和蛋的问题.当鼠标点击外面时,我希望我的小部件窗口关闭.据我了解,我的小部件没有鼠标事件,因为在它之外发生了点击.有一个SetFocus插槽,但其对应或焦点丢失在哪里?我没有为我的班级调用"focusOutEvent".
我的窗口小部件窗口是一个窗口小部件的子窗口,它总是显示在我的主窗口上,它是一个"Qt :: ToolTip",所以我认为可能会出现一些问题.有什么方法吗?
我的目标:我有一个自定义工具栏小部件,其上的按钮可能有"下拉"小部件.这些下拉小部件没有标准的窗口框架.我不希望他们从主窗口"窃取"字幕焦点,我希望他们一旦用户点击他们所在地区以外的屏幕上的ANYWHERE就会消失.我很难找到一个在Qt上没有妥协的策略来完成这项工作.
我错过了什么吗?(打赌我).
Jas*_*enX 15
我用了:
setWindowFlags(Qt::FramelessWindowHint | Qt::Popup);
Run Code Online (Sandbox Code Playgroud)
这似乎在OSX和Windows上运行良好.正确地出现在我的窗口,并没有从我的主窗口的标题窃取的焦点,而焦点丢失事件是否正确,只要我点击它外面叫.
如果您的小部件可以具有焦点,并且"窃取"某些其他小部件的标题焦点,则会更容易.像这样的东西可以工作:
class ToolBarWidget : public QWidget
{
Q_OBJECT
public:
explicit ToolBarWidget(QWidget * parent = 0)
{
setFocusPolicy(Qt::ClickFocus);
}
protected:
void focusOutEvent(QFocusEvent * event)
{
close();
}
}
Run Code Online (Sandbox Code Playgroud)
当你创建任何小部件时,你会做:
ToolBarWidget * pWidget = new ToolBarWidget(this);
pWidget->show();
pWidget->setFocus();
Run Code Online (Sandbox Code Playgroud)
完成!好吧,我想不安静.首先,您不希望ToolBarWidget首先获得任何焦点.其次,您希望用户能够在任何地方单击并隐藏ToolBarWidget.因此,您可以跟踪您创建的每个ToolBarWidget.例如,在'QList ttWidgets'成员变量中.然后,每当你创建一个新的ToolBarWidget时,你都会这样做:
ToolBarWidget * pWidget = new ToolBarWidget(this);
pWidget->installEventFilter(this);
pWidget->show();
Run Code Online (Sandbox Code Playgroud)
并在您的主要小部件类中,实现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);
}
Run Code Online (Sandbox Code Playgroud)
这将有效.因为这样,即使您的ToolTabWidgets没有获得焦点,主窗口小部件中的其他窗口小部件也会有焦点.一旦改变(无论用户是否从窗口中,或在其中的另一个控件上,或者在这种情况下,按下按键或鼠标按钮,控件将到达该eventFilter()函数并关闭所有选项卡小部件.
顺便说一下,为了从其他小部件中捕获MouseButtonPress,KeyPress等,你也需要在它们上面安装EventEilFilter,或者只是在你的主小部件中重新实现QWidget :: event(QEvent*event)函数,然后寻找那些那里的事件.