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