I'm new to Qt, C++ and signals and slots. I'm trying to load in a webpage. Then set a label_3's text to the title of the webpage. To do this I figured I had to connect the loadFinished signal to my custom function. But I'm having trouble doing just that.

I've read up on the manual, different examples and other questions, but I'm stuck. This is a excerpt from code I have so far.

How do I properly connect the signal loadFinished() to my function labelSetText()?

main.cpp

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

    return a.exec();
}

mainwindow.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);
}

mainwindow.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

EDIT: This is the error I get

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)));
                                             ^
有帮助吗?

解决方案

That's not how connections work. A signal-slot connection can only pass data from the signal into the slot. It can't pass arbitrary variables like you do. The only way you could write your connect statement is as follows (the this argument is unnecessary):

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

This of course doesn't work, because the signal and slot are incompatible. You of course don't need the intermediate slot, since a label already has the slot you want, but it doesn't help:

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

Note that you should not have connect(&view, ... since view is already a pointer-to-QObject.

To do it, you need to leverage C++11:

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

The lambda syntax translates into a functor class instance with copies of taxt and this as members. The compiler essentially creates the following, on the fly:

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));

Of course this means that if you want to use Qt 4 signals and slots, you need to add the taxt member to your MainWindow class, and create a slot to do what the functor does. So, for 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());
    ...
  }
};

Note that you shouldn't be connecting repeatedly. For Qt 4 style connection, move the connect to MainWindow's constructor. For Qt 5 style connection, you need to break the connection once it fires.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top