合并所有按钮,文本,检查按钮可将事件更改为单个插槽

时间:2012-04-19 20:09:59

标签: qt qt4

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

3 个答案:

答案 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中消失或改变。它将通过贝斯特的方式通知您每个可能出现的信号,因此您可以进行一些内省并检查您收到的信号是否符合您的要求。