Проблема с подключением loadFinished SIGNAL к пользовательскому слоту

Я новичок в Qt, C++, сигналах и слотах. Я пытаюсь загрузить веб-страницу. Затем установите текст label_3 в заголовок веб-страницы. Для этого я решил, что мне нужно подключить сигнал loadFinished к моей пользовательской функции. Но у меня проблемы с этим.

Я прочитал руководство, разные примеры и другие вопросы, но я застрял. Это отрывок из кода, который у меня есть до сих пор.

Как правильно подключить сигнал loadFinished() к моей функции labelSetText()?

main.cpp

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

главное окно.cpp

void MainWindow::on_pushButton_clicked()
{
    QString webAdress = ui->lineEdit->text();

    QWebView *view = ui->webView;
    view->load(QUrl(webAdress));

    QString taxt = view->title();

    connect(&view,  SIGNAL(loadFinished(bool)),
            this,   SLOT(labelSetText(taxt)));

    QWebPage * webPage = view->page();
}

void MainWindow::labelSetText(QString titleStr)
{
    ui->label_3->setText(titleStr);
}

главное окно.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QWidget>

namespace Ui {
class MainWindow;
}

class MainWindow : public QWidget
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_pushButton_clicked();
    void labelSetText(QString titleStr);

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

РЕДАКТИРОВАТЬ: это ошибка, которую я получаю

E:\_Programming\C++\playAround\mainwindow.cpp:37: error: no matching function for call to 'MainWindow::connect(QWebView**, const char*, MainWindow* const, const char*)'
             this,   SLOT(labelSetText(taxt)));
                                             ^

person Einar    schedule 07.02.2014    source источник


Ответы (1)


Соединения работают не так. Соединение сигнал-слот может передавать данные только из сигнала в слот. Он не может передавать произвольные переменные, как вы. Единственный способ, которым вы могли бы написать оператор подключения, выглядит следующим образом (аргумент this не нужен):

connect(view, SIGNAL(loadFinished(bool)), SLOT(labelSetText(QString)));

Это, конечно, не работает, потому что сигнал и слот несовместимы. Вам, конечно, не нужен промежуточный слот, так как метка уже имеет нужный вам слот, но это не помогает:

connect(view, SIGNAL(loadFinished(bool)), ui->label_3, SLOT(setText(QString)));

Обратите внимание, что у вас не должно быть connect(&view, ..., так как view уже является указателем на QObject.

Для этого вам нужно использовать C++11:

connect(view, &QWebView::loadFinished, [=,this](){
  this->ui->label_3->setText(taxt);
});

Синтаксис лямбда преобразуется в экземпляр класса функтора с копиями taxt и this в качестве членов. Компилятор по существу создает следующее на лету:

class Functor_1 {
  MainWindow * _this;
  QString taxt;
public:
  MyFunctor_1(MainWindow * a1, const QString & a2) : _this(a1), taxt(a2) {}
  void operator() {
    _this->ui->label_3->setText(taxt);
  }
}

...
connect(view, &QWebView::loadFinished, Functor_1(this, taxt));

Конечно, это означает, что если вы хотите использовать сигналы и слоты Qt 4, вам нужно добавить элемент taxt в ваш класс MainWindow и создать слот, чтобы делать то, что делает функтор. Итак, для Qt 4:

class MainWindow : public QMainWindow {
  Q_OBJECT
  QString m_taxt;
  Q_SLOT void loadFinished() {
    ui->label_3->setText(m_taxt);
  }
  ...
  Q_SLOT void on_pushButton_clicked() {
    QString webAdress = ui->lineEdit->text();

    QWebView *view = ui->webView;
    view->load(QUrl(webAdress));
    m_taxt = view->title();

    connect(view, SIGNAL(loadFinished(bool)), SLOT(loadFinished());
    ...
  }
};

Обратите внимание, что вы не должны подключаться повторно. Для соединения в стиле Qt 4 переместите соединение в конструктор MainWindow. Для подключения в стиле Qt 5 вам необходимо разорвать соединение после его запуска.

person Kuba hasn't forgotten Monica    schedule 08.02.2014