我的 Qt eventFilter() 不会停止事件,因为它应该
我的 eventFilter 存在根本性错误,因为它允许 每个 单个事件通过,而我想停止 所有事情.我已经阅读了很多关于 QEvent
、eventFilter()
等的文档,但显然我遗漏了一些重要内容.本质上,我正在尝试为基于 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::cout
在 if(...)
中,我看到它确实会在将事件发送到 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.
相关文章