qt - 如何在自定义 Qt 类上安装事件过滤器?
问题描述
我想在 Qt 中的自定义类的对象上安装事件过滤器。所以我在QtGuiApplication1
Qt Designer 上创建了一个项目,并创建了一个简单的类,myClass
它有一个小部件和一个用于绘制彩色矩形的 QGraphicsView。
在头文件中:
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_QtGuiApplication1.h"
#include "myClass.h"
class QtGuiApplication1 : public QMainWindow
{
Q_OBJECT
public:
QtGuiApplication1(QWidget *parent = Q_NULLPTR);
private:
Ui::QtGuiApplication1Class ui;
bool eventFilter(QObject *obj, QEvent *ev);
myClass* myClass_;
};
在.cpp
#include "QtGuiApplication1.h"
QtGuiApplication1::QtGuiApplication1(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
myClass_ = new myClass(this, QRect(100, 100, 200, 200));
myClass_->installEventFilter(this);
}
bool QtGuiApplication1::eventFilter(QObject * obj, QEvent * ev)
{
if (obj == myClass_)
{
bool hi = true;
}
return false;
}
myClass 代码在这里:
myClass的头文件:
#ifndef MYCLASS_H
#define MYCLASS_H
#include <QObject>
#include <QGraphicsView>
class myClass : public QObject
{
Q_OBJECT
public:
explicit myClass(QObject *parent = 0);
myClass();
myClass(QWidget* parent, QRect inRect);
private:
QWidget * widget;
QGraphicsView* qGraph_back;
QGraphicsScene* scene_back;
};
#endif /
myClass的cpp文件:
#include "myClass.h"
myClass::myClass(QObject *parent) :
QObject(parent)
{
}
myClass::myClass()
{
}
myClass::myClass(QWidget* parent, QRect inRect)
{
widget = new QWidget(parent);
qGraph_back = new QGraphicsView(widget);
scene_back = new QGraphicsScene(qGraph_back);
widget->setGeometry(inRect);
scene_back->setSceneRect(0,0,inRect.width(),inRect.height());
qGraph_back->setBackgroundBrush(QColor(0, 0, 255, 80));
qGraph_back->setScene(scene_back);
qGraph_back->show();
}
我想获取myClass_
对象的所有事件,例如鼠标事件,但我不能,并且事件过滤器不起作用。如何在对象上安装 eventfilter?
解决方案
事件过滤器仅适用于您的MyClass
实例中的事件。不是为了它的孩子。
因此,您的方法中的事件(例如鼠标单击或移动)qGraph_back
将不可见eventFilter
。
当您在小部件中添加子项时,QChildEvent
会引发一个事件。您可以使用它在所有孩子(和孙子等)上安装事件过滤器。MyClass
但是,在添加孩子之前,您必须在您的设备上安装事件过滤器。
一个简单的例子:
class Listener: public QObject
{
public:
Listener(): QObject()
{}
bool eventFilter(QObject* object, QEvent* event)
{
qDebug() << Q_FUNC_INFO << object << event;
if (event->type() == QEvent::ChildAdded)
{
QChildEvent* ev = dynamic_cast<QChildEvent*>(event);
ev->child()->installEventFilter(this);
}
return false;
}
};
class Widget: public QWidget
{
public:
Widget(QObject* parent) : QWidget()
{
installEventFilter(parent);
QGraphicsView* view = new QGraphicsView(this);
auto layout = new QHBoxLayout(this);
layout->addWidget(view);
layout->addWidget(new QLabel("Foobar"))
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Listener* listener = new Listener();
Widget* w = new Widget(listener);
w->show();
return app.exec();
}
如您所见,QLabel
现在将发送到侦听器中的事件。但是,您无法从视图中看到事件,因为它们被...中的视口小部件捕获。QGraphicsView
您必须处理添加的孩子有视口(继承自QAbstractItemView
等)并且它变得更加复杂的情况。
因此,如果您必须知道用户何时点击您的视图,则使用信号/槽而不是事件过滤器会更容易。
推荐阅读
- ruby-on-rails - 尝试在 Ruby/Rails 中使用 SFTP.download 理解和下载文件
- go - 类型定义和接口转换
- react-native - 修复 react-native init 上的“找不到模块‘libnpx’”
- azure - QnA Maker 中缺少端点密钥
- spring-boot - 更新到 jdk 11 后,wildfly 17 中的 Springboot 部署失败
- javascript - 在颜色处设置未定义的属性“背景颜色”
- list - 在 Flutter 中按类型排序列表和排序
- python - 从循环列表中自动创建单个变量
- python - 如何在 Python 中保存多个文件?
- python - 熊猫数据框检查一行的多列中是否存在值