有没有办法在不使用每个小部件的connect()函数的情况下捕获所有gui事件,如点击按钮,更改文本,切换复选框,进入同一个插槽?
答案 0 :(得分:3)
如果您的窗口小部件是表单的一部分,并且您希望将更改提交给模型(或SQL数据库),则使用QDataWidgetMapper
可能比您想要的更适应。
无论如何,这些信号(除了不可检查按钮的按钮clicked
信号之外)被声明为NOTIFY
属性的USER
信号(在Q_PROPERTY
声明中)
您可以使用Qt的元对象系统连接列表中的所有小部件:
void connectChanged(QWidgetList list, QObject *target, const char *targetSlot) {
foreach(QWidget *widget, list) {
const QMetaObject * mo = widget->metaObject();
QMetaProperty property = mo->userProperty();
// Skip non user-editable widgets (QLabel, QGraphicsScene...)
if(!property.isValid() || !property.hasNotifySignal()) {
qDebug() << "Skipped" << mo->className();
continue;
}
// Non checkable buttons have to be handled separately
QAbstractButton *button = qobject_cast<QAbstractButton*>(widget);
if (button && !button->isCheckable()) {
QObject::connect(button, SIGNAL(clicked()), target, targetSlot);
} else {
// QMetaMethod notifySignal() returns the raw signal signature
// for instance "toggled(bool)", we need the signature that would be
// returned by the macro SIGNAL: "2toggled(bool)"
QByteArray signalSignature;
signalSignature.append(char('0' + QSIGNAL_CODE));
signalSignature.append(property.notifySignal().signature());
QObject::connect(widget, signalSignature, target, targetSlot);
}
}
}
// connect all child widgets to a slot:
connectChanged(this->findChildren<QWidget*>(), this, SLOT(dataChanged()));
PS:这也会将QScrollBar::valueChanged(int)
的{{1}}信号连接到您的广告位。
答案 1 :(得分:0)
QCoreApplication::notify
可能就是你想要的。它的文档详细介绍了其他可能更好的方法。
答案 2 :(得分:0)
看看这个code。它使用Qt QObject系统的未记录(私有)部分。据我所知,Qt4中没有更改或删除。但由于它是无证/私有部分,它可能会在未来的Qt4版本或Qt5中消失或改变。它将通过贝斯特的方式通知您每个可能出现的信号,因此您可以进行一些内省并检查您收到的信号是否符合您的要求。