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

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

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

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

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

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

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

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

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

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

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

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

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

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


person Yattabyte    schedule 06.10.2014    source источник


Ответы (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);
}
person Oleg Shparber    schedule 06.10.2014
comment
И если вы ищете пример кода, вы, вероятно, могли бы посмотреть на обе привязки PyQt. - person o11c; 06.10.2014
comment
Да! Большое спасибо! Это именно то, что я искал! Я знал, что должен быть какой-то способ сделать это, поскольку соединения происходят во время выполнения, а не во время компиляции. Спасибо, что нашли время включить этот пример. Теперь все работает. - person Yattabyte; 07.10.2014
comment
int index = emitter- ›metaObject () -› indexOfSignal (QMetaObject :: normalizedSignature (qPrintable (signalName))); signalName здесь должно быть aSignal (), а не aSignal? - person Luppiter; 24.02.2021