实现这一点的一种简单方法,不需要任何子类化,是一个信号源,它监视某个对象上的事件并发出相关信号:
// main.cpp - this is a single-file example
#include <QtWidgets>
class MouseButtonSignaler : public QObject {
Q_OBJECT
bool eventFilter(QObject * obj, QEvent * ev) Q_DECL_OVERRIDE {
if ((ev->type() == QEvent::MouseButtonPress
|| ev->type() == QEvent::MouseButtonRelease
|| ev->type() == QEvent::MouseButtonDblClick)
&& obj->isWidgetType())
emit mouseButtonEvent(static_cast<QWidget*>(obj),
static_cast<QMouseEvent*>(ev));
return false;
}
public:
Q_SIGNAL void mouseButtonEvent(QWidget *, QMouseEvent *);
MouseButtonSignaler(QObject * parent = 0) : QObject(parent) {}
void installOn(QWidget * widget) {
widget->installEventFilter(this);
}
};
emit关键字是一个空宏,Qt定义如下:
#define emit
它仅供人类用作文档辅助前缀,编译器和moc 会忽略它。作为文档辅助,它意味着:以下方法调用是信号发射。信号只是方法,其实现由moc 为您生成——这就是为什么我们必须在下面的#include "main.moc" 中包含moc 为该文件中的对象类生成的所有实现。否则,信号没有什么特别或神奇的。在此示例中,您可以在构建文件夹中查找名为 main.moc 的文件,并查看 void MouseButtonSignaler::mouseButtonEvent( .. ) 的实现(定义)。
然后您可以在任意数量的小部件上安装这样的信号器,例如 QLabel:
int main(int argc, char ** argv) {
QApplication app(argc, argv);
MouseButtonSignaler signaler;
QWidget w;
QVBoxLayout layout(&w);
QLabel label("text");
QLineEdit edit;
layout.addWidget(&label);
layout.addWidget(&edit);
signaler.installOn(&label);
QObject::connect(&signaler, &MouseButtonSignaler::mouseButtonEvent,
[&label, &edit](QWidget*, QMouseEvent * event) {
if (event->type() == QEvent::MouseButtonPress)
edit.setText(label.text());
});
w.show();
return app.exec();
}
#include "main.moc"