Qt: подключение сигналов и слотов из текста

Как бы я подключил сигнал и слот из 2 объектов, когда имена объектов, сигналы и слоты все указаны в текстовом файле?

Получение правильных имен объектов не является проблемой, так как я могу легко перебрать массив и сравнить имена с местом в файле, но должен быть какой-то способ, которым я могу вернуть сигнал и слот из файла и использовать его в функции подключения, например:

connect(rtnObj1(line),SIGNAL(rtnSignal(line)),rtnObj2(line),SLOT(rtnSlot(line)));

где функции rtn возвращают имя объекта / сигнал / слот, а "строка" - это текущая строка QString из файла.

Единственный известный мне способ - это буквально кодировать каждую комбинацию и сравнивать QStrings с операторами if, но это было бы невероятно утомительно, так как количество комбинаций было бы невероятно высоким.

Примечание. Вот упрощенный пример, демонстрирующий, как существует эта проблема.

Кадр 1: 4 QComboBoxes. Первый и третий содержат имена объектов, второй содержит сигналы, четвертый содержит слоты. Каждый элемент, конечно, является QString в этих списках. Нажатие на кнопку добавляет новую строку в файл, записывая текст, выбранный из каждого поля.

Кадр 2: уже содержит необходимые объекты. Считывая файл, он сопоставляет объекты, определенные в списке, с уже созданными и соединяет их, как описано в файле.

Достаточно легко создать объект на основе данных, которые хранятся в файле, но как создать / извлечь сигнал и слот из файла?

Редактировать: Разве можно подключиться так?

connect(objectA, "", objectB, "");

Потому что я только что узнал, что мой код будет скомпилирован таким образом, однако всякий раз, когда я пытаюсь вставить имена слотов или сигналов, я просто получаю сообщение об ошибке:

QObject:: connect: используйте макрос SIGNAL для привязки Tile::clicked

1 ответ

Решение

Ваша проблема легко решается с помощью одного из следующих статических методов QObject::connect():

QMetaObject::Connection QObject::connect(
    const QObject *sender, const QMetaMethod &signal,
    const QObject *receiver, const QMetaMethod &method,
    Qt::ConnectionType type = Qt::AutoConnection)

Прежде всего, вам нужны указатели на объекты отправителя и получателя. Существует несколько способов хранения пула объектов. Я бы предложил сохранить все объекты в QHash:

QHash<QString, QObject *> m_objects; // I use QObject as a generic example

Теперь можно найти указатель на любой объект для эффективного подключения.

Следующим шагом будет получение объектов QMetaMethod для сигнала отправителя и слота получателя из соответствующих объектов QMetaObject. Используйте QObject::metaObject() QMetaObject экземпляров.

Вот полный код функции, которая соединяет два объекта, используя только строковые параметры:

void dynamicConnect(const QString &senderName, const QString &signalName,
                    const QString &receiverName, const QString &slotName)
{
    QObject *emitter = m_objects.value(senderName);
    int index = emitter->metaObject()
            ->indexOfSignal(QMetaObject::normalizedSignature(qPrintable(signalName)));
    if (index == -1) {
        qWarning("Wrong signal name!");
        return;
    }
    QMetaMethod signal = emitter->metaObject()->method(index);

    QObject *receiver = m_objects.value(receiverName);
    index = receiver->metaObject()
            ->indexOfSlot(QMetaObject::normalizedSignature(qPrintable(slotName)));
    if (index == -1) {
        qWarning("Wrong slot name!");
        return;
    }
    QMetaMethod slot = receiver->metaObject()->method(index);

    QObject::connect(emitter, signal, receiver, slot);
}
Другие вопросы по тегам