Learn what Felgo offers to help your business succeed. Start your free evaluation today! Felgo for Your Business

Forums

OverviewFelgo 2 Support (Qt 5) › Custom QQuickItem in iOS not working

Tagged: 

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • #24244

    Patrik Dusek

    Hi all,

    I’m going insane with a strange behaviour in iOS. I create a custom QQuickItem based on the MaskedMouseArea from the examples.

    It works perfectly with Android and Desktop. But when I click on my component in iOS I get only the message:

    “stale focus object QQuickloader…” and nothing happens. I can see from the logs that the component constructor in c++ was called and I get no other

    message that something is wrong. But after the stale message no mouse event is triggered.

    
    #ifndef MASKEDMOUSEAREA_H
    #define MASKEDMOUSEAREA_H
    
    #include <QImage>
    #include <QQuickItem>
    #include <QQmlEngine>
    
    class MaskedMouseArea : public QQuickItem
    {
        Q_OBJECT
        Q_PROPERTY(bool pressed READ isPressed NOTIFY pressedChanged)
        Q_PROPERTY(bool containsMouse READ containsMouse NOTIFY containsMouseChanged)
        Q_PROPERTY(QUrl maskSource READ maskSource WRITE setMaskSource NOTIFY maskSourceChanged)
        Q_PROPERTY(qreal alphaThreshold READ alphaThreshold WRITE setAlphaThreshold NOTIFY alphaThresholdChanged)
    
    public:
        MaskedMouseArea(QQuickItem *parent = 0);
    
        Q_INVOKABLE void scaleToSized(int width, int height);
        bool contains(const QPointF &point) const;
    
        bool isPressed() const { return m_pressed; }
        bool containsMouse() const { return m_containsMouse; }
    
        QUrl maskSource() const { return m_maskSource; }
        void setMaskSource(const QUrl &source);
    
        qreal alphaThreshold() const { return m_alphaThreshold; }
        void setAlphaThreshold(qreal threshold);
    
    signals:
        void pressed();
        void released();
        void clicked();
        void canceled();
        void pressedChanged();
        void maskSourceChanged();
        void containsMouseChanged();
        void alphaThresholdChanged();
    
    protected:
        void setPressed(bool pressed);
        void setContainsMouse(bool containsMouse);
        void mousePressEvent(QMouseEvent *event);
        void mouseReleaseEvent(QMouseEvent *event);
        void hoverEnterEvent(QHoverEvent *event);
        void hoverLeaveEvent(QHoverEvent *event);
        void mouseUngrabEvent();
    
    private:
        bool m_pressed;
        QUrl m_maskSource;
        QImage m_maskImage;
        QPointF m_pressPoint;
        qreal m_alphaThreshold;
        bool m_containsMouse;
    };
    
    #endif
    
    #include "maskedmousearea.h"
    
    #include <QStyleHints>
    #include <QGuiApplication>
    #include <qqmlfile.h>
    #include <QDebug>
    
    MaskedMouseArea::MaskedMouseArea(QQuickItem *parent)
        : QQuickItem(parent),
          m_pressed(false),
          m_alphaThreshold(0.0),
          m_containsMouse(false)
    {
        setAcceptHoverEvents(true);
        setAcceptedMouseButtons(Qt::LeftButton);
    }
    
    void MaskedMouseArea::setPressed(bool pressed)
    {
        if (m_pressed != pressed) {
            m_pressed = pressed;
            emit pressedChanged();
        }
    }
    
    void MaskedMouseArea::setContainsMouse(bool containsMouse)
    {
        if (m_containsMouse != containsMouse) {
            m_containsMouse = containsMouse;
            emit containsMouseChanged();
        }
    }
    void MaskedMouseArea::scaleToSized(int width, int height){
        m_maskImage = m_maskImage.scaledToWidth(width);
      //  m_maskImage = m_maskImage.scaledToHeight(height);
        qDebug() << "target Size: " << m_maskImage.width();
    }
    
    void MaskedMouseArea::setMaskSource(const QUrl &source)
    {
        if (m_maskSource != source) {
            m_maskSource = source;
            m_maskImage = QImage(QQmlFile::urlToLocalFileOrQrc(source));
            qDebug() << "target Width: " << width();
            emit maskSourceChanged();
        }
    }
    
    void MaskedMouseArea::setAlphaThreshold(qreal threshold)
    {
        if (m_alphaThreshold != threshold) {
            m_alphaThreshold = threshold;
            emit alphaThresholdChanged();
        }
    }
    
    bool MaskedMouseArea::contains(const QPointF &point) const
    {
        if (!QQuickItem::contains(point) || m_maskImage.isNull())
            return false;
    
        QPoint p = point.toPoint();
    
    //    if (p.x() < 0 || p.x() >= m_maskImage.width() ||
    //        p.y() < 0 || p.y() >= m_maskImage.height()){
    //        return false;
    //    } else {
    
    //        qDebug() << " in image";
    //    }
    
        if (p.x() < 0 || p.x() >= width() ||
            p.y() < 0 || p.y() >= height()){
            return false;
        } else {
    
          //  qDebug() << " in image";
        }
    
    
        qreal r = qBound<int>(0, m_alphaThreshold * 255, 255);
    //    if (qAlpha(m_maskImage.pixel(p)) > r)
    //        qDebug() << "inside";
        return qAlpha(m_maskImage.pixel(p)) > r;
    }
    
    void MaskedMouseArea::mousePressEvent(QMouseEvent *event)
    {
        qDebug() << "mouse" ;
        setPressed(true);
        m_pressPoint = event->pos();
        event->setAccepted(false);
        emit pressed();
    }
    
    void MaskedMouseArea::mouseReleaseEvent(QMouseEvent *event)
    {
        setPressed(false);
        emit released();
    
        const int threshold = qApp->styleHints()->startDragDistance();
        const bool isClick = (threshold >= qAbs(event->x() - m_pressPoint.x()) &&
                              threshold >= qAbs(event->y() - m_pressPoint.y()));
    
        if (isClick)
            emit clicked();
        event->setAccepted(false);
    }
    
    void MaskedMouseArea::mouseUngrabEvent()
    {
        setPressed(false);
        emit canceled();
    }
    
    void MaskedMouseArea::hoverEnterEvent(QHoverEvent *event)
    {
        Q_UNUSED(event);
        setContainsMouse(true);
        event->setAccepted(false);
    }
    
    void MaskedMouseArea::hoverLeaveEvent(QHoverEvent *event)
    {
        Q_UNUSED(event);
        setContainsMouse(false);
        event->setAccepted(false);
    }
    
        qmlRegisterType<MaskedMouseArea>("com.pxx.pd", 1,0, "MaskedMouseArea");
    
    AppImage {
        id: mainImage
        property string sourceImage
        property string region
        anchors.fill: parent
        fillMode: Image.PreserveAspectFit
        smooth: true
        source: sourceImage
        MaskedMouseArea {
            id: imageMask
            anchors.fill: parent
            alphaThreshold: 0.8
            maskSource: sourceImage
            onPressed: {
                showRegion(parent, mainImage.region)
            }
            Component.onCompleted: {
                scaleToSized(width, height)
            }
        }
        Behavior on scale {
            NumberAnimation { duration: 400 }
        }
    }
    

    As I said it works on the other plattforms. So is there anything else I have to do on iOS?

    Thx,

    patrik

    #24245

    Patrik Dusek

    Found the solution. Its about this:

    QImage(QQmlFile::urlToLocalFileOrQrc(source));

    Seems to be an old methode from Qt which is no longer documented.

    This seems not work on iOS.

     

    #24246

    Alex
    Felgo Team

    Hi Patrik,

    great that you found it. I was juet beginning to look into that issue, would have probably also taken me quite a bit to dig that up. Thanks for saving me a bit of time 🙂

    The masked mouse area is also a pretty cool example!

    Cheers,
    Alex

Viewing 3 posts - 1 through 3 (of 3 total)

RSS feed for this thread

You must be logged in to reply to this topic.

Qt_Technology_Partner_RGB_475 Qt_Service_Partner_RGB_475_padded