Search code examples
c++qtsignals-slots

How does QObject connect() work with no "receiver" argument?


I'm going through Qt5's MediaPlayer example, and some of its connect statements are rather confusing:

player.h:

class Player : public QWidget
{
    Q_OBJECT

    public:
        Player(QWidget *parent = 0);
        ~Player();

    signals:
        void fullScreenChanged(bool fullScreen);

    private slots:
        void open();
        void durationChanged(qint64 duration);
        void positionChanged(qint64 progress);
        void metaDataChanged();

        void previousClicked();

        void seek(int seconds);
        void jump(const QModelIndex &index);
        void playlistPositionChanged(int);

        void statusChanged(QMediaPlayer::MediaStatus status);
        void bufferingProgress(int progress);
        void videoAvailableChanged(bool available);

        void displayErrorMessage();

     #ifndef PLAYER_NO_COLOROPTIONS
       void showColorDialog();
     #endif
       void addToPlaylist(const QStringList &fileNames);

private:
    void setTrackInfo(const QString &info);
    void setStatusInfo(const QString &info);
    void handleCursor(QMediaPlayer::MediaStatus status);
    void updateDurationInfo(qint64 currentInfo);

    QMediaPlayer *player;
    QMediaPlaylist *playlist;
    VideoWidget *videoWidget;
    QLabel *coverLabel;
    QSlider *slider;
    QLabel *labelDuration;
    QPushButton *fullScreenButton;
#ifndef PLAYER_NO_COLOROPTIONS
    QPushButton *colorButton;
    QDialog *colorDialog;
#endif

   QLabel *labelHistogram;
   HistogramWidget *histogram;
   QVideoProbe *probe;

   PlaylistModel *playlistModel;
   QAbstractItemView *playlistView;
   QString trackInfo;
   QString statusInfo;
   qint64 duration;
};

player.cpp:

Player::Player(QWidget *parent)
    : QWidget(parent)
    , videoWidget(0)
    , coverLabel(0)
    , slider(0)
#ifndef PLAYER_NO_COLOROPTIONS
    , colorDialog(0)
#endif
{
    player = new QMediaPlayer(this);
    // owned by PlaylistModel
    playlist = new QMediaPlaylist();
    player->setPlaylist(playlist);

    connect(player, SIGNAL(durationChanged(qint64)), SLOT(durationChanged(qint64)));
    connect(player, SIGNAL(positionChanged(qint64)), SLOT(positionChanged(qint64)));
    connect(player, SIGNAL(metaDataChanged()), SLOT(metaDataChanged()));
    connect(playlist, SIGNAL(currentIndexChanged(int)),      SLOT(playlistPositionChanged(int)));
    connect(player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
        this, SLOT(statusChanged(QMediaPlayer::MediaStatus)));
    connect(player, SIGNAL(bufferStatusChanged(int)), this, SLOT(bufferingProgress(int)));
    connect(player, SIGNAL(videoAvailableChanged(bool)), this, SLOT(videoAvailableChanged(bool)));
    connect(player, SIGNAL(error(QMediaPlayer::Error)), this, SLOT(displayErrorMessage()));
    ...

It looks like the connect() uses the old Qt syntax:

connect(sender, SIGNAL(valueChanged(QString,QString)),
         receiver, SLOT(updateValue(QString)) );

However, in the player.cpp connect() expressions, there is only a sender (player), and no receiver. The line

connect(player, SIGNAL(durationChanged(qint64)), SLOT(durationChanged(qint64)));

seems to connect QMediaPlayer's durationChanged() signal to Player's durationChanged()` slot, but shouldn't that be

connect(player, SIGNAL(durationChanged(qint64)), this, SLOT(durationChanged(qint64)));

??


Solution

  • No, it is correct. You can do this because durationChanged() is a slot in this so you can call the member-function version of connect():

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

    There are sender, signal, slot and type. The documentation gives a good explanation:

    This function overloads connect(). Connects signal from the sender object to this object's method. Equivalent to connect(sender, signal, this, method, type).