我的Qt eventFilter()不会停止事件,它应该 [英] My Qt eventFilter() doesn't stop events as it should

查看:732
本文介绍了我的Qt eventFilter()不会停止事件,它应该的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的eventFilter根本有问题,因为它允许所有单个事件通过,而我想停止所有 .我已经阅读了许多关于QEventeventFilter()等的文档,但是显然我缺少一些重要的东西.本质上,我试图基于QDialog为弹出窗口类创建自己的模态功能.我想实现自己的功能,因为内置的setModal(true)包含许多功能,例如播放QApplication::Beep(),我要排除在外. 基本上,我想丢弃所有转到创建我的弹出窗口的QWidget(窗口)的事件.到目前为止,我是

Something is fundamentally wrong with my eventFilter, as it lets every single event through, while I want to stop everything. I've read lots of documentation on QEvent, eventFilter() and so on, but obviously I'm missing something big. Essentially, I'm trying to create my own modal-functionality for my popup-window class based on QDialog. I want to implement my own since the built-in setModal(true) includes a lot of features, e.g. playing QApplication::Beep(), that I want to exclude. Basically, I want to discard all events going to the QWidget (window) that created my popup. What I have so far is,

// popupdialog.h
#ifndef POPUPDIALOG_H
#define POPUPDIALOG_H

#include <QDialog>
#include <QString>

namespace Ui {class PopupDialog;}

class PopupDialog : public QDialog
{
   Q_OBJECT
public:
    explicit PopupDialog(QWidget *window=0, QString messageText="");
    ~PopupDialog();
private:
    Ui::PopupDialog *ui;
    QString messageText;
    QWidget window; // the window that caused/created the popup
    void mouseReleaseEvent(QMouseEvent*); // popup closes when clicked on
    bool eventFilter(QObject *, QEvent*);
};

...

// popupdialog.cpp
#include "popupdialog.h"
#include "ui_popupdialog.h"

PopupDialog::PopupDialog(QWidget *window, QString messageText) :
    QDialog(NULL), // parentless
    ui(new Ui::PopupDialog),
    messageText(messageText),
    window(window)
{
    ui->setupUi(this);
    setAttribute(Qt::WA_DeleteOnClose, true); // Prevents memory leak
    setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
    ui->message_text_display->setText(messageText);

    window->installEventFilter(this);

    //this->installEventFilter(window); // tried this also, just to be sure ..
}

PopupDialog::~PopupDialog()
{
    window->removeEventFilter(this);
    delete ui;
}

// popup closes when clicked on
void PopupDialog::mouseReleaseEvent(QMouseEvent *e)
{
    close();
}

这是问题所在,过滤器无法正常工作.请注意,如果我写一个std::coutif(...)中,我看到只要事件发送到window,它就会触发,只是不会停止它们.

Here's the problem, the filter doesn't work. Note that if I write a std::cout inside the if(...), I see that it does trigger whenever events are sent to window, it just doesn't stop them.

bool PopupDialog::eventFilter(QObject *obj, QEvent *e)
{
    if( obj == window )
        return true; //should discard the signal (?)
    else
        return false; // I tried setting this to 'true' also without success
}

当用户与主程序交互时,可以这样创建一个PopupDialog:

When the user interacts with the main program, a PopupDialog can be created like this:

PopupDialog *popup_msg = new PopupDialog(ptr_to_source_window, "some text message");
popup_msg->show();
// I understand that naming the source 'window' might be a little confusing.
// I apologise for that. The source can in fact be any 'QWidget'.

其他所有功能都可以正常工作.仅事件过滤器失败. 我希望过滤器删除发送到创建弹出窗口的事件;例如点击鼠标和按键,直到弹出窗口关闭.当有人指出我的代码中的一个小错误时,我期望我会感到非常尴尬.

Everything else works as expected. Only the event filter fails. I want the filter to remove events sent to the window that created the popup; like mouse clicking and key pressing, until the popup is closed. I'm expecting to be extremely embarrassed when someone points out a trivial fix in my code.

推荐答案

您必须忽略所有到达window窗口小部件树中的事件.因此,您需要在应用程序范围内安装eventFilter并检查是否要过滤的对象是window的后代.换句话说:替换

You have to ignore all events that arrive in the widget tree of the window. Therefore, you need to install the eventFilter application-wide and check, if the object you are filtering on is a descendant of window. In other words: Replace

window->installEventFilter(this);

作者

QCoreApplication::instance()->installEventFilter(this);

并以这种方式实现事件过滤器功能:

and implement the event filter function this way:

bool PopupDialog::eventFilter(QObject *obj, QEvent *e)
{
    if ( !dynamic_cast<QInputEvent*>( event ) )
        return false;

    while ( obj != NULL )
    {
        if( obj == window )
            return true;
        obj = obj->parent();
    }
    return false;
}

我尝试了一下,对其进行了测试,它对我有用.

I tried it, tested it and it worked for me.

注意:根据我的经验,在Qt中使用事件过滤器有点混乱,因为所发生的事情并不十分透明.期望错误会不时弹出.如果您和您的客户因此对灰显的主窗口没有问题,则可以考虑禁用主窗口.

Note: Using event filters in Qt is a bit messy in my experience, since it is not quite transparent what is happening. Expect bugs to pop up from time to time. You may consider disabling the main window instead, if you and your clients don't have a problem with the grayed-out main window as a consequence.

这篇关于我的Qt eventFilter()不会停止事件,它应该的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆