سؤال

أنا فقط أتعلم Qt باستخدام C++.لقد نجحت في تنفيذ الإشارات والفتحات لاحتجاز الأحداث القياسية مثل ButtonPushed(), ، إلخ.ومع ذلك، أريد أن يتم استدعاء وظيفة عندما أقوم بالماوس والخروج من ملف QLabel.يبدو الأمر كذلك QHoverEvent سأفعل ما أحتاج إليه، ولكن لا يبدو أنني أستطيع العثور على أي برامج تعليمية أو أمثلة حول كيفية تنفيذ ذلك.وهل يتم ذلك بنفس طريقة الإشارات والفتحات؟.حاولت:

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

..ولكن لم يتم استدعاء الوظيفة عندما قمت بالتمرير فوق الملصق.

هذه هي الوظيفة المدرجة في ملف الرأس كفتحة عامة:

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

هل يمكن لأي شخص مساعدتي في اكتشاف ذلك أو توجيهي إلى مثال جيد؟

يحرر:

بعد قراءة المنشور أدناه، لم أجد setFlag() عضو للاتصال بأداة التصنيف الخاصة بي، لكنني حاولت:

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

وتحديثها TestFunc() وفقاً لذلك.ولكن لا يزال لا شيء يحدث عندما أقوم بالماوس.

بعد النظر لست متأكدا QLabel حتى أنه يرث mouseMoveEvent() حتى من QWidget.إذا كان هذا صحيحًا، فهل هناك عنصر واجهة مستخدم يفعل ذلك، أو قائمة بالكائنات التي ترثها في مكان ما؟.كل ما يمكنني قوله من الوثائق الموجودة على موقعهم هو عدد الوظائف الموروثة التي يمتلكها الكائن.

هل كانت مفيدة؟

المحلول

<ع> استخدام الإشارات وفتحات لهذا الغرض لا هو الذهاب إلى العمل.

وmouseMoveEvent() ليس إشارة أو التلوي طريقة، ولا يمكن ان تكون مرتبطة إلى فتحة.

سوف

وشاء subclasses ترث الطبقة القطعة وmouseMoveEvent() الغلابة تسمح لك للحصول على الماوس تحرك الأحداث، ولكن هذا هو وسيلة الوزن الثقيل جدا لإنجاز هذا (ويضيف فئة واحدة أكثر لقاعدة المصدر).

وبدلا من ذلك، أن تنظر في تنفيذ طريقة eventFilter() على الطبقة MyDialog وتثبيته على QLabel. مع هذا الأسلوب تصفية الحدث، يمكنك اعتراض كل الأحداث لمثيل QObject معينة.

وهنا هو وثائق حول شروط الحدث.

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

وبالإضافة إلى ذلك، من خلال النظر في نموذج التعليمات البرمجية، أنصح لكم ان نتوقف لحظة للتحقيق في ما تفعل SIGNAL() وSLOT() وحدات الماكرو. يمكنك أن ترى كيف يتم تعريفها في $QTDIR/src/corelib/kernel/qobjectdefs.h

نصائح أخرى

ووفقا لصلة الوثيقة التي تعطيك ذاهبون فقط للحصول على هذا QHoverEvent إذا القطعة لديه علم Qt::WA_Hover.

وبعد بناء على دعوة القطعة:

widget->setAttribute(Qt::WA_Hover);

ونرى ما اذا كان يعمل.

وهناك طريقة أخرى لتحقيق نفس النتيجة لتجاوز mouseMoveEvent() في عنصر واجهة المستخدم
لاحظ أن هذه الوظيفة أيضا لن يكون يسمى عادة إلا إذا كنت الاتصال على:

widget->setMouseTracking(true);

وهذا هو أساسا كيف تنفذ QT الحدث تحوم داخليا.

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

كيو تي::WA_Hover

تجبر QT على إنشاء أحداث الطلاء عندما يدخل الماوس أو يترك عنصر واجهة المستخدم.عادة ما يتم استخدام هذه الميزة عند تنفيذ الأنماط المخصصة ؛راجع مثال الأنماط للحصول على التفاصيل.

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

هذا QStyle::polish() يتم استدعاء الحمل الزائد مرة واحدة على كل عنصر واجهة مستخدم باستخدام النمط.نحن نعيد تنفيذه لتعيين Qt::WA_Hover ميزة على QPushButtons و QComboBoxes.عند ضبط هذه السمة ، تقوم QT بإنشاء أحداث الطلاء عندما يدخل مؤشر الماوس أو يترك عنصر واجهة المستخدم.هذا يجعل من الممكن تقديم أزرار الدفع و comboBoxes بشكل مختلف عندما يكون مؤشر الماوس فوقها.

كيفية استقبال أحداث الدخول والخروج على أ QWidget

  1. قم بتعيين سمة القطعة لـ WA_Hover

    // in your widget's constructor (probably)
    this->setAttribute(Qt::WA_HOVER, true);
    
  2. ينفذ QWidget::enterEvent() و 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. منتهي

QHoverEvent في QWidget

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

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

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

// 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);
}

تحديث:

مثال بسيط

قم بتحريك الزر وشاهد تغير العد.انظر إلى مخرجات التطبيق لمزيد من المعلومات.

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

امل ان يساعد.

كنت أواجه نفس المشكلة، وتوصلت إلى تصميم الحل التالي:

في عنصر واجهة المستخدم الرئيسي الخاص بي، أرغب في معالجة أحداث التمرير لبعض الكائنات المحددة.لهذا السبب، قمت بإنشاء فتحتين على جهازي MainWindow:

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

ثم قمت بإنشاء فئة تصفية الأحداث مثل هذا:

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;
}

يمكنك أن ترى أن هذا الفصل سيتم تشغيله إما HoverIn أو HoverOut اعتمادًا على ما حدث. هذا النهج لا يحتاج إلى إعدادات Qt::WA_Hover

الآن كخطوة أخيرة، نحتاج إلى تحديد العناصر التي سيتم تصفيتها وتوصيل الإشارات والفتحات.سأقوم بإنشاء مؤشر خاص لتصفية الأحداث في mainwindow.h

class MainWindow : public QWidget
{
    Q_OBJECT

...

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

private:

    HoverEventFilter* hoverEventFilter;

...

};

وفي المنشئ، وأضيف هذا:

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*)));

الآن عندما أرغب في تلقي أحداث التمرير على كائن ما، أقوم فقط بتعيين مرشح الأحداث عليه، مثل هذا:

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

ما بقي هو التنفيذ onHoverIn و onHoverOut في MainWindow.كلاهما يشتركان في نفس الفكرة لذلك سأعرض فقط onHoverIn

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

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

يمكنك توسيع هذا بسهولة، لمعالجة أحداث التمرير على عنصر جديد، ما عليك سوى تعيين مستمع للحدث عليه والاهتمام بما ترغب في القيام به في onHoverIn و onHoverOut طُرق.لا حاجة لفئة فرعية أي الحاجيات.

وQHoverEvent فقط من أجل الحاجيات تحوم، وتريد لتنفيذ enterEvent وleaveEvent معالجات من قبل إن شاء subclasses ترث القطعة بدلا من ذلك. إذا كنت ترغب في استخدام عامل تصفية الحدث بدلا من ذلك، أنواع الأحداث المقابلة هي QEvent::Enter وQEvent::Leave.

إذا كنت ببساطة الحاجة لتغيير مظهر من القطعة، قد ترغب في النظر في الأنماط كيو تي، لأنها توفر محدد :hover.

وتحتاج إلى فئة فرعية أو تصفية focusInEvent و <لأ href = " http://doc.trolltech.com/4.5/qwidget.html#focusOutEvent "يختلط =" نوفولو noreferrer "> focusOutEvent تلك القطعة معينة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top