Search code examples
qtsignals-slots

Not receiving a signal from a subclassed QVideoWidget


I'm developing a video player application, I have subclassed QVideoWidget, then I promoted QWidget in my ui file to this subclassed QVideoWidget.

Now I want to call a function defined in another class by a signal from the subclassed QVideoWidget.

So I defined a signal that I emit when the user presses the videowidget, and connected it to a slot in the other class (the function I want to call), but the slot never gets called.

videowidget.h :

#ifndef VIDEOWIDGET_H
#define VIDEOWIDGET_H

#include <QVideoWidget>
#include <QMouseEvent>
#include <QObject>

class videowidget : public QVideoWidget
{
    Q_OBJECT
public:
     videowidget();
signals:
    void videoClicked();
protected:
    void mouseDoubleClickEvent(QMouseEvent *event) override;
    void mousePressEvent(QMouseEvent *event) override;
};
#endif // VIDEOWIDGET_H

videowidget.cpp :

#include "videowidget.h"
videowidget::videowidget()
{

}

void videowidget::mouseDoubleClickEvent(QMouseEvent *event)
{

    setFullScreen(!isFullScreen());
    event->accept();
}

void videowidget::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        emit videoClicked();
    }
    else
    {
        return;
    }
}

widget.h :

private slots:
     void videoClicked();
private:
   videowidget *videoPlayer;

widget.cpp :

Widget::Widget()
{
    videoPlayer = new videowidget();

    /*Widget*/
    Bottom = ui->Bottom; /*Bottom was declare in Player.h as a QWidget*/
    connect(videoPlayer, &videowidget::videoClicked, this, &Widget::videoClicked);
}

void Widget::videoClicked()
{
    Bottom->setVisible(false);
    qDebug()<<"pressed from slot";
}

If I print something in the function that emits the signal, it works, but the slot from the other class is never called.

I also have tried to directly print a string instead of calling the slot, but it also doesn't work.


Solution

  • Here's a minimal reproducible example with comments to explain what was wrong and how to fix it:

    widget.h

    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    #include <QVideoWidget>
    #include "videowidget.h"
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class Widget; }
    QT_END_NAMESPACE
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        Widget(QWidget *parent = nullptr);
        ~Widget();
    
    private slots:
        void videoClicked();
    
    private:
        Ui::Widget *ui;
        videowidget *videoPlayer;
        QWidget *Bottom;
    };
    #endif // WIDGET_H
    
    

    widget.cpp

    #include "widget.h"
    #include "./ui_widget.h"
    #include "videowidget.h"
    
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
        , ui(new Ui::Widget)
    {
        ui->setupUi(this);
        
        //The problem's here
    
        //this new object is unnecessary and it's not being set visible 
        videoPlayer = new videowidget(this);
         
        ui->video_player->show();
    
        //I removed Bottom because it was an unnecessary intermediate
        //use ui->video_player directly as a sender, since it is the promoted widget
        //and the one being displayed and clicked
        connect(ui->video_player, &videowidget::videoClicked, this, &Widget::videoClicked);
        
        //videoPlayer was not the widget you were clicking, hence why you never got a response
        //connect(videoPlayer, &videowidget::videoClicked, this, &Widget::videoClicked);
    }
    
    Widget::~Widget()
    {
        delete ui;
    }
    
    void Widget::videoClicked()
    {
        qDebug()<<"pressed";
        ui->video_player->setVisible(false);
    }
    
    
    
    

    videowidget.h

    #ifndef VIDEOWIDGET_H
    #define VIDEOWIDGET_H
    
    #include <QVideoWidget>
    #include <QMouseEvent>
    
    class videowidget : public QVideoWidget
    {
        Q_OBJECT
    
    public:
        videowidget(QWidget *parent = nullptr);
    
    signals:
        void videoClicked();
    
    protected:
        void mouseDoubleClickEvent(QMouseEvent *event) override;
        void mousePressEvent(QMouseEvent *event) override;
    };
    
    #endif // VIDEOWIDGET_H
    
    

    videowidget.cpp

    #include "videowidget.h"
    
    videowidget::videowidget(QWidget *parent)
    {
    }
    
    void videowidget::mouseDoubleClickEvent(QMouseEvent *event)
    {
        setFullScreen(!isFullScreen());
        event->accept();
    }
    
    void videowidget::mousePressEvent(QMouseEvent *event)
    {
        if(event->button() == Qt::LeftButton)
        {
            videoClicked();
        }
    }