我需要能够排除事件循环处理的一组事件;我知道有一些标志可以传递到 processEvents 方法(例如 QEventLoop::ExcludeUserInputEvents,它只处理不是用户输入的事件,但将用户输入事件留在那里供以后处理),但是有没有办法只处理事件的特定子集(或者同等地,排除特定子集)?我已经能够使用事件过滤器完成类似的事情,但是事件被丢弃而不是简单地不处理,这不是我想要的。我无法找到一种方法来做到这一点,因此提出了这个问题;是否必须重写 QT 的内部结构才能做到这一点,或者是否有一些功能用于此目的?预先感谢!
在全局级别,您可以尝试覆盖
QCoreApplication::notify()
事件处理程序。在那里您可以创建一组您忽略的事件类型。
在下面的示例中,我覆盖
QApplication
并忽略所有与鼠标单击相关的事件。单击小部件时,不应显示任何消息。如果您注释掉 notify()
覆盖,将显示调试消息。
#include <QApplication>
#include <QDebug>
#include <QWidget>
class Widget : public QWidget
{
public:
void mousePressEvent(QMouseEvent *) override
{
qDebug() << "mouse button pressed";
}
};
class Application : public QApplication
{
public:
Application(int argc, char *argv[]) : QApplication(argc, argv)
{
}
bool notify(QObject *object, QEvent *event) override
{
// e.g. sink for all mouse click events
static QSet<int> ignoredEvents = { QEvent::MouseButtonPress, QEvent::MouseButtonRelease, QEvent::MouseButtonDblClick };
if (ignoredEvents.contains(event->type()))
{
return true;
}
return QApplication::notify(object, event);
}
};
int main(int argc, char *argv[])
{
Application a(argc, argv);
Widget w;
w.show();
return a.exec();
}
我意识到这是一个迟到的回复,但我最近遇到了同样的问题。对于那些面临类似问题并且更喜欢综合解决方案而不是阅读大量评论的人,我用代码示例整理了答案。
简而言之,解决方案涉及处理所有事件。如果您想推迟活动,只需将其存储以供以后使用即可。
示例,让我们修改@hifile-app-best-file-manager答案中的代码。我们将存储计划丢弃的事件,然后稍后重新应用它们。下面是我们应该如何扩展 Application 类:
class Application : public QApplication
{
public:
Application(int argc, char *argv[]);
void activetePostponing(bool active); // to determine should we pospotone events
bool notify(QObject *object, QEvent *event) override;
private:
bool _postponingActive{false};
std::vector<std::pair<QObject *, QEvent *>> _buffer; // for buffered events
};
我们将添加一个新函数来尝试应用存储的事件:
void Application::activetePostponing(bool active)
{
_postponingActive = active;
if(active)
return;
for(auto& [obj, event]: _buffer)
QCoreApplication::postEvent(obj, event);
_buffer.clear();
}
我们还将修改现有的
notify
函数来存储事件而不是丢弃它们:
bool Application::notify(QObject *object, QEvent *event) override
{
// e.g. sink for all mouse click events
static QSet<int> ignoredEvents = { QEvent::MouseButtonPress, QEvent::MouseButtonRelease, QEvent::MouseButtonDblClick };
if (_postponingActive && ignoredEvents.contains(event->type()))
{
_buffer.emplace_back(object, event->clone());
return true;
}
return QApplication::notify(object, event);
}
通过这些更改,主函数现在允许更改推迟状态。这是完整的代码:
#include <QApplication>
#include <QDebug>
#include <QWidget>
#include <vector>
#include <tuple>
class Widget : public QWidget
{
public:
void mousePressEvent(QMouseEvent *) override
{
qDebug() << "mouse button pressed";
}
};
class Application : public QApplication
{
public:
Application(int argc, char *argv[]) : QApplication(argc, argv)
{
}
bool notify(QObject *object, QEvent *event) override
{
// e.g. sink for all mouse click events
static QSet<int> ignoredEvents = { QEvent::MouseButtonPress, QEvent::MouseButtonRelease, QEvent::MouseButtonDblClick };
if (_postponingActive && ignoredEvents.contains(event->type()))
{
_buffer.emplace_back(object, event->clone());
return true;
}
return QApplication::notify(object, event);
}
void activetePostponing(bool active)
{
_postponingActive = active;
if(active)
return;
for(auto& [obj, event]: _buffer)
QCoreApplication::postEvent(obj, event);
_buffer.clear();
}
private:
bool _postponingActive{false};
std::vector<std::pair<QObject *, QEvent *>> _buffer; // for buffered events
};
int main(int argc, char *argv[])
{
Application a(argc, argv);
Widget w;
QObject::connect(&w, /*some event here*/, &a, &Application::activetePostponing); // here we just state for postponing
w.show();
return a.exec();
}