Pergunta

Estou aprendendo Qt com C ++. Tenho sinais e slots para interceptar eventos padrão como ButtonPushed(), etc. implementado com sucesso No entanto, eu quero ter uma função chamada quando eu mouse sobre e mouse para fora de um QLabel. Parece QHoverEvent vai fazer o que eu preciso, mas eu não consigo para encontrar qualquer tutoriais ou exemplos sobre como implementar isso. É feito da mesma maneira como sinais e slots ?. Eu tentei:

connect(ui.lbl_test, SIGNAL(QHoverEvent), this, SLOT(TestFunc(QEvent::Type type, const QPoint & pos, const QPoint & oldPos)));

.. mas a função não se chamou quando eu pairava sobre o rótulo.

Aqui está a função, listados no arquivo de cabeçalho como um slot pública:

void MyDialog::TestFunc(QEvent::Type type, const QPoint & pos, const QPoint & oldPos) {
     QMessageBox::information(this, tr("Hey"), tr("Listen!"));
}

Alguém pode me ajudar a descobrir isso ou me aponte para um bom exemplo?

EDIT:

Depois de ler um post abaixo, eu encontrei nenhum membro setFlag() para pedir meu widget rótulo, mas eu fiz tentativa:

    ui.lbl_test->setMouseTracking(true);
    connect(ui.lbl_test, SIGNAL(ui.lbl_test->mouseMoveEvent()), this, SLOT(TestFunc(QMouseEvent *event)));

E TestFunc() actualizado em conformidade. Mas ainda nada acontece quando eu mouse sobre.

Depois de olhar eu não tenho certeza QLabel mesmo herda a mouseMoveEvent () até mesmo de QWidget. Se isso for verdade, há um widget que faz, ou uma lista de objetos que herdam lo em algum lugar ?. Tudo o que posso dizer a partir da documentação em seu site é quantas funções um objeto herdou ..

Foi útil?

Solução

Usando sinais e slots para este fim não está indo para o trabalho.

mouseMoveEvent() não é um sinal ou meta-modo e não pode ser ligada a uma ranhura.

Subclassificação a classe widget e substituindo mouseMoveEvent() irá permitir que você obtenha rato-move-eventos, mas que é uma maneira muito pesado para alcançar este objetivo (e acrescenta mais uma classe para sua base de origem).

Em vez disso, considere a implementação de um método eventFilter() em sua classe MyDialog e instalá-lo no QLabel. Com este método filtro de eventos, você pode interceptar todos os eventos de uma determinada ocorrência QObject.

Aqui está a documentação sobre filtros de eventos.

http://doc.qt.io/qt-4.8 /eventsandfilters.html#event-filters

Além disso, através do olhar para o exemplo de código, eu recomendo que você tome um momento para investigar o que os SIGNAL() e SLOT() macros fazer. Você pode ver como eles são definidos no $QTDIR/src/corelib/kernel/qobjectdefs.h

Outras dicas

De acordo com o link do documento que você dá você está indo só para obter este QHoverEvent se o seu widget tem a bandeira Qt::WA_Hover.

Depois de construir a chamada Widget:

widget->setAttribute(Qt::WA_Hover);

e ver se funciona.

Outra forma de alcançar o mesmo resultado é substituir mouseMoveEvent() em seu widget
Observe que essa função também não será normalmente chamado a menos que você ligue para:

widget->setMouseTracking(true);

Esta é, basicamente, como QT implementa o evento em foco internamente.

http://qt-project.org/doc/qt -5 / qwidget.html # enterEvent

http://qt-project.org/doc/qt -5 / qwidget.html # leaveEvent

http://qt-project.org/doc /qt-5/qt.html#widget-attributes

Qt :: WA_Hover

Forças Qt para gerar eventos de pintura quando o mouse entra ou sai do ferramenta. Este recurso é normalmente usado na implementação personalizada estilos; veja o exemplo Styles para mais detalhes.

http: / /qt-project.org/doc/qt-5/qtwidgets-widgets-styles-example.html#norwegianwoodstyle-class-implementation

Essa sobrecarga QStyle::polish() é chamado uma vez em cada Widget tirada usando o estilo. Nós reimplementar-lo para definir o atributo Qt::WA_Hover em QPushButtons e QComboBoxes. Quando esse atributo é definido, Qt gera eventos de pintura quando o ponteiro do mouse entra ou sai do ferramenta. Isso torna possível para tornar botões e comboboxes diferente quando o ponteiro do mouse está sobre eles.

Como receber Enter e Leave eventos em um QWidget

  1. Defina o atributo Widget para WA_Hover

    // in your widget's constructor (probably)
    this->setAttribute(Qt::WA_HOVER, true);
    
  2. Implementar QWidget::enterEvent() e QWidget::leaveEvent().

    void Widget::enterEvent(QEvent * event)
    {
        qDebug() << Q_FUNC_INFO << this->objectName();
        QWidget::enterEvent(event);
    }
    
    void Widget::leaveEvent(QEvent * event)
    {
        qDebug() << Q_FUNC_INFO << this->objectName();
        QWidget::leaveEvent(event);
    }
    
  3. Feito

QHoverEvent em QWidget

http://qt-project.org/doc/qt -5 / qhoverevent.html # detalhes

http://qt-project.org/doc/qt -5 / qobject.html # evento

http://qt-project.org/doc/qt -5 / qwidget.html # evento

// in your widget's constructor (probably)
this->setAttribute(Qt::WA_HOVER, true);
// ...

void Widget::hoverEnter(QHoverEvent * event) {qDebug() << Q_FUNC_INFO << this->objectName();}
void Widget::hoverLeave(QHoverEvent * event) {qDebug() << Q_FUNC_INFO << this->objectName();}
void Widget::hoverMove(QHoverEvent * event) {qDebug() << Q_FUNC_INFO << this->objectName();}

bool Widget::event(QEvent * e)
{
    switch(e->type())
    {
    case QEvent::HoverEnter:
        hoverEnter(static_cast<QHoverEvent*>(e));
        return true;
        break;
    case QEvent::HoverLeave:
        hoverLeave(static_cast<QHoverEvent*>(e));
        return true;
        break;
    case QEvent::HoverMove:
        hoverMove(static_cast<QHoverEvent*>(e));
        return true;
        break;
    default:
        break;
    }
    return QWidget::event(e);
}

UPDATE:

Simples Exemplo

Passe o botão e ver a mudança contagem. Olhe para a saída do aplicativo para obter mais informações.

https://gist.github.com/peteristhegreat/d6564cd0992351f98aa94f869be36f77

Espero que ajude.

Eu estava tendo o mesmo problema, eu vim para o seguinte projeto de solução:

Na minha widget principal, eu gostaria de processar pairar eventos de alguns objetos selecionados. Por esta razão, eu criei 2 slots no meu MainWindow:

public slots:
    void onHoverIn(QObject* object);
    void onHoverOut(QObject* object);

Em seguida, eu criei uma classe de Filtro de Eventos como este:

hovereventfilter.h

#ifndef HOVEREVENTFILTER_H
#define HOVEREVENTFILTER_H

#include <QObject>
#include <QEvent>

class HoverEventFilter : public QObject
{
    Q_OBJECT
public:
    explicit HoverEventFilter(QObject *parent = 0);

signals:
    void HoverIn(QObject *);
    void HoverOut(QObject *);

public slots:

protected:
    bool eventFilter(QObject *watched, QEvent *event);
};

#endif // HOVEREVENTFILTER_H

hovereventfilter.cpp

#include "hovereventfilter.h"

HoverEventFilter::HoverEventFilter(QObject *parent) : QObject(parent)
{

}

bool HoverEventFilter::eventFilter(QObject *watched, QEvent *event)
{

    QEvent::Type t = event->type();

    switch(t){
    case QEvent::Enter:
        emit HoverIn(watched);
        break;

    case QEvent::Leave:
        emit HoverOut(watched);
        break;
    default:
        return false;
    }

    return true;
}

Você pode ver esta classe irá disparar quer HoverIn ou HoverOut dependendo do que aconteceu. Esta abordagem não precisa de configurações do Qt::WA_Hover

Agora, como último passo, precisamos instruir quais elementos devem ser filtrados e sinais de conexão e slots. Vou criar um ponteiro privada para filtro de eventos em mainwindow.h

class MainWindow : public QWidget
{
    Q_OBJECT

...

public slots:
    void onHoverIn(QObject* object);
    void onHoverOut(QObject* object);

private:

    HoverEventFilter* hoverEventFilter;

...

};

E no construtor, eu acrescentar o seguinte:

this->hoverEventFilter = new HoverEventFilter(this);

connect(this->hoverEventFilter, SIGNAL(HoverIn(QObject*)), this, SLOT(onHoverIn(QObject*)));
connect(this->hoverEventFilter, SIGNAL(HoverOut(QObject*)), this, SLOT(onHoverOut(QObject*)));

Agora, sempre que eu quiser receber pairar eventos em algum objeto, eu apenas definir filtro de eventos sobre ele, como este:

this->ui->someLabelOrWhatever->installEventFilter(this->hoverEventFilter);

O que resta é a implementação de onHoverIn e onHoverOut em MainWindow. Ambos compartilham a mesma idéia por isso vou mostrar apenas onHoverIn

void MainWindow::onHoverIn(QObject *object)
{
    QString objectName = object->objectName();

    switch(objectName){
        // do something depending on name of the widget
    }
}

Você pode estender isso tão facilmente, para processar pairar eventos novo item, você apenas definir um ouvinte de evento sobre ele e cuidar do que você deseja fazer nos métodos onHoverIn e onHoverOut. Não há necessidade de subclasse quaisquer widgets.

QHoverEvent apenas para widgets em foco, você deseja implementar os manipuladores enterEvent e leaveEvent por subclasse o widget em seu lugar. Se você quiser usar um filtro de eventos em vez disso, os tipos de eventos correspondentes são QEvent::Enter e QEvent::Leave.

Se você simplesmente precisa para mudar a aparência do widget, você pode querer olhar para as folhas de estilo do Qt, como eles fornecem um seletor :hover.

Você precisa subclasse ou filtro focusInEvent e focusOutEvent desse widget específico.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top