1

有没有办法在不为每个小部件使用 connect() 函数的情况下将所有 gui 事件(如按钮单击、文本更改、复选框切换)捕获到同一个插槽中?

4

3 回答 3

3

如果您的小部件是表单的一部分,并且您希望将更改提交到模型(或 SQL 数据库),则使用 aQDataWidgetMapper可能比您想要的更适合。

无论如何,除了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:这也会将 s 的QScrollBar::valueChanged(int)信号连接QTextEdit到您的插槽。

于 2012-04-20T01:44:40.520 回答
0

QCoreApplication::notify可能是你想要的。它的文档详细介绍了其他一些可能更好的方法。

于 2012-04-19T22:31:09.993 回答
0

看看这段代码。它使用 Qt QObject 系统的未记录(私有)部分。据我所知,这在 Qt4 中没有更改或删除。但由于它是无证/私有部分,它可能会在未来的某些 Qt4 版本或 Qt5 中消失或更改。它会基本通知您发出的每个可能的信号,因此您可以进行一些自省并检查您收到的信号是否是您需要的。

于 2012-04-20T13:00:11.437 回答