列出从 qt 应用程序发出的所有信号
list all signals emitted from qt application
我继承了一个遗留的 qt gui 应用程序。我需要做的第一件事是创建一个日志文件,记录每个用户交互,比如单击按钮、编辑 QLineEdit 等等。这是因为用户显然无法分辨如何重现特定错误,因此他们希望在打开错误时读取此日志文件,以检查用户在发现错误时执行的步骤。
我看到可以重写 QCoreApplication
中的 notify
方法以获得所有事件,并且它有效,但这不是我想要的,因为它似乎可以管理只有操作系统的事件,如聚焦等,它不处理信号的发射。
当然我可以更改代码并在例如 textChanged
信号和报告它的 lambda 之间创建连接,但在这种情况下我需要更改所有 che 代码。有没有办法以另一种方式实现相同的结果,而无需重写应用程序的大部分内容?
您可以使用 QApplication::allWidgets()
.
列出应用程序中的所有小部件
然后,您可以列出每个小部件的所有信号(使用 QObject::metaObject()
)并将它们连接到 logger。
一个简单的例子:
class Spy: public QObject {
Q_OBJECT
public:
Spy();
public slots:
void log();
};
void Spy::log()
{
auto i = senderSignalIndex(); // The signal that fired this slot
auto signal = sender()->metaObject()->method(i);
qDebug() << sender() << signal.methodSignature();
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
Spy* spy = new Spy();
QMetaMethod log = spy->metaObject()->method(spy->metaObject()->indexOfSlot("log()")); // in order to use the right QObject::connect signature
for (auto widget: a.allWidgets())
{
auto metaObject = widget->metaObject();
for (int i = 0; i != metaObject->methodCount(); ++i)
{
auto method = metaObject->method(i);
if (method.methodType() != QMetaMethod::Signal) // We want to connect all the signals. We don't care about the other methods
continue;
widget->connect(widget, method, spy, log);
}
}
return a.exec();
}
如果要显示参数,则必须改进代码。
您还可以过滤对象以仅记录重要信号(例如,仅记录来自按钮的 clicked
信号)
我继承了一个遗留的 qt gui 应用程序。我需要做的第一件事是创建一个日志文件,记录每个用户交互,比如单击按钮、编辑 QLineEdit 等等。这是因为用户显然无法分辨如何重现特定错误,因此他们希望在打开错误时读取此日志文件,以检查用户在发现错误时执行的步骤。
我看到可以重写 QCoreApplication
中的 notify
方法以获得所有事件,并且它有效,但这不是我想要的,因为它似乎可以管理只有操作系统的事件,如聚焦等,它不处理信号的发射。
当然我可以更改代码并在例如 textChanged
信号和报告它的 lambda 之间创建连接,但在这种情况下我需要更改所有 che 代码。有没有办法以另一种方式实现相同的结果,而无需重写应用程序的大部分内容?
您可以使用 QApplication::allWidgets()
.
然后,您可以列出每个小部件的所有信号(使用 QObject::metaObject()
)并将它们连接到 logger。
一个简单的例子:
class Spy: public QObject {
Q_OBJECT
public:
Spy();
public slots:
void log();
};
void Spy::log()
{
auto i = senderSignalIndex(); // The signal that fired this slot
auto signal = sender()->metaObject()->method(i);
qDebug() << sender() << signal.methodSignature();
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
Spy* spy = new Spy();
QMetaMethod log = spy->metaObject()->method(spy->metaObject()->indexOfSlot("log()")); // in order to use the right QObject::connect signature
for (auto widget: a.allWidgets())
{
auto metaObject = widget->metaObject();
for (int i = 0; i != metaObject->methodCount(); ++i)
{
auto method = metaObject->method(i);
if (method.methodType() != QMetaMethod::Signal) // We want to connect all the signals. We don't care about the other methods
continue;
widget->connect(widget, method, spy, log);
}
}
return a.exec();
}
如果要显示参数,则必须改进代码。
您还可以过滤对象以仅记录重要信号(例如,仅记录来自按钮的 clicked
信号)