QT - emit signal when hover a QLabel - c++

I would like to emit a signal when hovering a QLabel with the mouse in QT.
Is it possible ?
If not, how can I do it ?
Thanks.

You can do hover handling without subclassing of QLabel. Try next code sample for it:
void LabelHoverHandler::attach(QLabel *label)
{
label->setAttribute(Qt::WA_Hover, true);
label->installEventFilter(this);
}
bool LabelHoverHandler::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::HoverEnter)
{
emit signalMouseHover(dynamic_cast<QLabel*>(obj) );
qDebug() << "HoverEnter";
}
return false;
}
LabelHoverHandler header file:
class LabelHoverHandler : public QObject
{
Q_OBJECT
public:
LabelHoverHandler(QObject *parent);
virtual ~LabelHoverHandler() {};
void attach(QLabel *label);
protected:
bool eventFilter(QObject *obj, QEvent *event);
signals:
void signalMouseHover(QLabel*);
};
Simply create an instance of LabelHoverHandler and call method attach() with a needed label as a parameter.

A possible implementation:
// mylabel.h
#ifndef MYLABEL_H
#define MYLABEL_H
#include <QLabel>
class MyLabel : public QLabel
{
Q_OBJECT
public:
MyLabel();
~MyLabel();
protected:
virtual void enterEvent(QEvent *ev);
virtual void leaveEvent(QEvent *ev);
private:
bool hover;
};
#endif // MYLABEL_H
and:
// mylabel.cpp
#include "mylabel.h"
#include <QEvent>
MyLabel::MyLabel()
{
hover = false;
setAttribute(Qt::WA_Hover, true);
}
MyLabel::~MyLabel()
{
}
void MyLabel::enterEvent(QEvent *ev)
{
if (!hover){
hover = true;
setText("Send signal here");
}
QLabel::enterEvent(ev);
}
void MyLabel::leaveEvent(QEvent *ev)
{
if (hover){
hover = false;
setText("Mouse leave area");
}
QLabel::leaveEvent(ev);
}

Related

QDialog Help [?] Button does not trigger whatsthis event

I have created following dialog using QT designer form class
#ifndef DLG_GAMMA_H
#define DLG_GAMMA_H
#include <QDialog>
namespace Ui {
class Dlg_Gamma;
}
class Dlg_Gamma : public QDialog
{
Q_OBJECT
public:
explicit Dlg_Gamma(QWidget *parent = nullptr);
~Dlg_Gamma() override;
private slots:
void on_horizontalSlider_valueChanged(int value);
void on_saveButton_clicked();
void on_discardButton_clicked();
void on_resetButton_clicked();
signals:
void savechanges(QString filter);
void discardchanges();
void reset();
private:
Ui::Dlg_Gamma *ui;
bool eventFilter(QObject *target, QEvent *event) override;
void closeEvent(QCloseEvent *dlg) override;
bool close_X;
};
#endif // DLG_GAMMA_H
.cpp
bool Dlg_Gamma::eventFilter(QObject *target, QEvent *event)
{
qDebug() << event->type();
}
However, clicking on help button, does not trigger any event.
Has anybody faced this issue before ?
Does anybody know solution ?
bool MyDialog::event(QEvent *e)
{
// reimplement event processing
if(e->type()==QEvent::WhatsThisClicked)
{
QWhatsThisClickedEvent ce = static_cast<QWhatsThisClickedEvent>(e);
....
return true;
}
return QDialog::event(e);
}
This is the event catcher.
To use event filter you need to install it:
installEventFilter(this) in the constructor of the Dialog.
You need to install eventFilter on your 'help button' when using eventFilter.
You need to insert kind of code below in the constructor of the 'Dlg_Gamma'
ui->helpButton->installEventFilter(this)
For more information, Please refer to the information below.
https://doc.qt.io/qt-5/eventsandfilters.html

QListWidget-derived: drop event not firing

A widget derived from QListWidget is the only widget on a window. Function "setAcceptDrops(true);" is used in its constructor, and "event->accept();" is called in its "dragEnterEvent". However, its "dropEvent" could not be triggered. Please check the whole source code (created using Qt 5.12.0) at
github.com/jianz-github/dropevent.
I have asked a question at Qt Drop event not firing. This situation is supposed to be the same, but it is not. Weird.
Thanks in advance for any help.
In this case, the solution is to overwrite the dragMoveEvent() method as well.
listbox.h
#ifndef LISTBOX_H
#define LISTBOX_H
#include <QListWidget>
#include <QDropEvent>
#include <QDragEnterEvent>
class ListBox : public QListWidget
{
public:
ListBox(QWidget *parent = nullptr);
protected:
void dropEvent(QDropEvent *event) override;
void dragEnterEvent(QDragEnterEvent *event) override;
void dragMoveEvent(QDragMoveEvent *event) override;
};
#endif // LISTBOX_H
listbox.cpp
#include "listbox.h"
#include <QDebug>
ListBox::ListBox(QWidget *parent) : QListWidget (parent)
{
setAcceptDrops(true);
}
void ListBox::dropEvent(QDropEvent *event)
{
qDebug() << "dropEvent"<<event;
}
void ListBox::dragEnterEvent(QDragEnterEvent *event)
{
event->acceptProposedAction();
}
void ListBox::dragMoveEvent(QDragMoveEvent *event)
{
event->acceptProposedAction();
}

QStackedWidget doesn't fire Drag and Drop events

I got simple class MyStackedWidget but looks like it doesn't fires drag and drop events - what am I doing wrong?
#ifndef MYSTACKEDWIDGET_H
#define MYSTACKEDWIDGET_H
#include <QStackedWidget>
class MyStackedWidget : public QStackedWidget
{
Q_OBJECT
public:
MyStackedWidget();
signals:
void dragEnterSignal(QDragEnterEvent *event);
void dropSignal(QDropEvent *event);
void dragMoveSignal(QDragMoveEvent *event);
void dragLeaveSignal(QDragLeaveEvent *event);
public slots:
void dragEnterEvent(QDragEnterEvent *event);
void dropEvent(QDropEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dragLeaveEvent(QDragLeaveEvent *event);
};
#endif // MYSTACKEDWIDGET_H
#include "mystackedwidget.h"
#include <QMimeData>
#include <QDragEnterEvent>
MyStackedWidget::MyStackedWidget()
{
setMouseTracking(true);
}
void MyStackedWidget::dragEnterEvent(QDragEnterEvent *event)
{
const QMimeData *mimeData = event->mimeData();
if(mimeData->hasUrls() && mimeData->urls().size() == 1) {
event->acceptProposedAction();
}
emit dragEnterSignal(event);
}
void MyStackedWidget::dropEvent(QDropEvent *event)
{
emit dropSignal(event);
}
void MyStackedWidget::dragMoveEvent(QDragMoveEvent *event)
{
emit dragMoveSignal(event);
}
void MyStackedWidget::dragLeaveEvent(QDragLeaveEvent *event)
{
emit dragLeaveSignal(event);
}

DoubleClick on QLabel

I have read this How to distinguish between mouseReleaseEvent and mousedoubleClickEvent on QGrapnhicsScene and this Distinguish between single and double click events in Qt in order to solve my problem. But they do not work. I created a class QLabel:
mouselabel.h
#ifndef MOUSELABEL_H
#define MOUSELABEL_H
#include <QLabel>
#include <QMouseEvent>
#include <QEvent>
#include <QDebug>
class MouseLabel : public QLabel
{
Q_OBJECT
public:
explicit MouseLabel(QWidget *parent = 0);
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
void leaveEvent(QMouseEvent *);
int x, y;
signals:
void Mouse_Pressed();
void Mouse_Position();
void Mouse_Left();
void Mouse_Release();
void Mouse_DoubleClick();
public slots:
};
#endif // MOUSELABEL_H
mouselabel.cpp
#include "mouselabel.h"
MouseLabel::MouseLabel(QWidget *parent) :
QLabel(parent)
{
}
void MouseLabel::mouseMoveEvent(QMouseEvent *event) {
this->x = event->x();
this->y = event->y();
emit Mouse_Position();
}
void MouseLabel::mousePressEvent(QMouseEvent *event)
{
emit Mouse_Pressed();
}
void MouseLabel::mouseReleaseEvent(QMouseEvent *event)
{
emit Mouse_Release();
}
void MouseLabel::mouseDoubleClickEvent(QMouseEvent *event)
{
emit Mouse_DoubleClick();
}
void MouseLabel::leaveEvent(QMouseEvent *)
{
emit Mouse_Left();
}
As described in the two links, in order to distinguish between a click and a double click, I created a timer and it starts when a mouserelease event happens and it stops when there is a double click mouse. But, this does not work. Can you help me to solve the problem?
The lightest possible solution is using a QBasicTimer, just have those 2 methods overloaded and the timer in your widget:
void mouseReleaseEvent(QMouseEvent *) {
if (timer.isActive()) {
timer.stop();
qDebug() << "double click";
}
else {
timer.start(300, this);
}
}
void timerEvent(QTimerEvent *) {
timer.stop();
qDebug() << "single click";
}
QBasicTimer timer;
The downside is a timer approach delays the single click, which is kind of annoying, but you could mask that, for example for selecting objects, using the mousePressEvent for immediate response.

Call the base class implementation

I was able to simulate the Right-Click event by subclassing the QTableWidget:
header file:
#ifndef QRIGHCLICKTABLE_H
#define QRIGHCLICKTABLE_H
#include <QTableWidget>
#include <QMouseEvent>
class QRightClickTable : public QTableWidget
{
Q_OBJECT
public:
explicit QRightClickTable(QWidget *parent = 0);
private slots:
void mousePressEvent(QMouseEvent *e);
signals:
void rightClicked();
public slots:
};
#endif // QRIGHCLICKTABLE_H
cpp file
QRightClickTable::QRightClickTable(QWidget *parent) :
QPushButton(parent)
{
}
void QRightClickTable::mousePressEvent(QMouseEvent *e)
{
if(e->button()==Qt::RightButton)
emit rightClicked();
}
QRightClickTable *button = new QRightClickTable(this);
ui->gridLayout->addWidget(button);
connect(button, SIGNAL(rightClicked()), this, SLOT(onRightClicked()));
void MainWindow::onRightClicked()
{
qDebug() << "User right clicked me";
}
Now, right-click works correctly, but there are other problems with QTableWidget: all other mouse events, such as the left click to select a cell, no longer work.
Can you help me? I know I need to call the base class implementation in my override of mousePressEvent, you could show me how with a little piece of code?
Change your event handler like this :
void QRightClickTable::mousePressEvent(QMouseEvent *e) {
if(e->button()==Qt::RightButton) {
emit rightClicked();
} else {
QTableWidget::mousePressEvent(e);
}
}