Qt 5.3 Сигналы и слоты, простая функция и лямбда-выражение

Я пытался написать программу, используя Qt 5.3, и стараюсь использовать сигналы и слоты в качестве практики. Я написал следующий код (часть кода):

void exitToWin()
    {
        exit(0);
    }
int main(int argc, char *argv[])
{

    QApplication a(argc, argv);
    MainWindow w;
    QMessageBox EndBox;
    QObject::connect((EndBox.button(QMessageBox::Ok)),SIGNAL(clicked()),exitToWin);
    w.show();
    EndBox.show();
    return a.exec();
}

Я даже меняю объявление функции на static и проверял выражение со скобками и без них, пока пишу команду connect. но хотя бы то, что документировал Qt и на что ориентировалась его IDE. также я прочитал здесь и я проверил это.
Более того, я попытался использовать лямбда-выражение, как показано ниже:

QObject::connect((EndBox.button(QMessageBox::Ok)),SIGNAL(clicked()),[=](){
    exit(0);
});

но все же я получаю сообщения об ошибках, указывающие на «Нет соответствующего вызова функции».
И в конце концов я должен сказать, что я использую Microsoft Windows 7.


person bahrami307    schedule 13.08.2014    source источник
comment
Вы пытались переписать это без объявления SIGNAL, как здесь: woboq.com/blog/cpp11- in-qt5.html ?   -  person Tanuki    schedule 13.08.2014
comment
@Тануки Да! Я читал это раньше.   -  person bahrami307    schedule 13.08.2014


Ответы (3)


Это работает на Qt 5.3:

#include <QtWidgets>

void exitToWin()
{
    exit(0);
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QMainWindow w;
    QMessageBox endBox;
    endBox.addButton(QMessageBox::Ok); // (2)
    endBox.connect(endBox.button(QMessageBox::Ok), 
                   &QAbstractButton::clicked, exitToWin); // (1)
    /* This works, too:
    endBox.connect(endBox.button(QMessageBox::Ok),
                   &QAbstractButton::clicked,
                   [] () { exit(0); });
    */
    w.show();
    endBox.show();
    return a.exec();
}

Вот почему:

(1) Вы можете использовать QObject endBox для связи между сигналом clicked QAbstractButton и вашей простой функцией exitToWin. Вы также не можете связать SIGNAL с простой функцией или лямбдой, поэтому вместо этого мы используем разновидность функции-члена.

(2) endBox фактически не получает кнопку OK по умолчанию. Когда вы упоминаете его в строке (1) в своем коде, он создает его, но не успевает (очевидно) передать указатель обратно в connect, поэтому мы сначала создаем его здесь.

person Alex Reinking    schedule 13.08.2014
comment
Большое спасибо, я проверил кое-что еще, как вы упомянули в строке 2, мы также можем использовать QPushButtom, это работает, я думаю, проблема связана с тем, что вы упомянули в строке 2. - person bahrami307; 13.08.2014
comment
Проблема все же с лямбда-выражением, можете помочь? - person bahrami307; 13.08.2014
comment
убедитесь, что у вас установлен флаг -std=c++11. - person Alex Reinking; 13.08.2014
comment
Я добавил встроенные шаги, но получил неизвестную ошибку команды - person bahrami307; 13.08.2014

Ваш код не будет работать по двум причинам:

Во-первых, у QMessageBox такого сигнала нет. См. документацию, чтобы узнать о сигналах, которые у него есть.

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

Если сигнал может передавать множество значений, и вы хотите, чтобы ваш слот выполнял определенную функцию только для выбора этих значений (в этом случае, только если передается значение QMessageBox::Ok), слот должен запросить значения, не оператор connect.

person RobbieE    schedule 13.08.2014
comment
Спасибо за ваш полезный совет. - person bahrami307; 13.08.2014

Поскольку метод connect() взят из QObject, его необходимо вызывать из дочернего элемента QObject, содержащего макрос Q_OBJECT. в его декларации. Запустив qmake, подготовьте класс к отправке сигналов и получению слотов.

person Martin Delille    schedule 13.08.2014
comment
QObject::connect — это статическая функция. - person RobbieE; 13.08.2014