Zoom in and out of a QTextEdit with touch pad gestures?



  • I need an OS agnostic way (it works on Linux, Windows and macOS) to, for example, pinch with two fingers on the computer touch pad and then zoom the text in a QTextEdit. I am unable to get the gesture to register. This is what I've got so far in my .cpp

    bool ZoomCode::gestureEvent(QGestureEvent *event) {
        qDebug() << "Gesture";
    }
    void ZoomCode::panTriggered(QPanGesture *e) {
        qDebug() << "Gesture pan";
    }
    void ZoomCode::pinchTriggered(QPinchGesture *e) {
        qDebug() << "Gesture pinch";
    }
    

    it doesn't register any gestures. I've also tried with QNativeGestureEvent and that doesn't work either. I'm running macOS Mojave 10.14 with Qt 5.12.1


  • Lifetime Qt Champion

    Hi
    I would try the Image Gestures Example
    alt text

    and see if Qt does register your touch in first place.



  • Gestures works perfectly in Image Gestures Example! I tried this as well but it doesn't work either

    bool ZoomCode::gestureEvent(QGestureEvent *event)
    {
        if (QGesture *swipe = event->gesture(Qt::SwipeGesture)) {qDebug() << "swipe";}
        else if (QGesture *pan = event->gesture(Qt::PanGesture)){qDebug() << "pan";}
        if (QGesture *pinch = event->gesture(Qt::PinchGesture)){qDebug() << "pinch";}
        return true;
    }
    


  • After trying

    bool ZoomCode::event(QEvent *event)
    {
        qDebug() << event->type();
        if (event->type() == QEvent::Gesture) {
            qDebug() << "gesture";
            gestureEvent(static_cast<QGestureEvent*>(event));
        }
    }
    
    bool ZoomCode::gestureEvent(QGestureEvent *event)
    {
        qDebug() << "ENTERED!";
        if (QGesture *swipe = event->gesture(Qt::SwipeGesture)) {qDebug() << "swipe"; /*exit(-1);*/}
        else if (QGesture *pan = event->gesture(Qt::PanGesture)){qDebug() << "pan"; /*exit(-1);*/}
        if (QGesture *pinch = event->gesture(Qt::PinchGesture)){qDebug() << "pinch"; /*exit(-1);*/}
        return true;
    }
    

    I see that the event is QEvent::NativeGesture, I'll try to follow that lead and I'll post my result soon.



  • when I do

    bool ZoomCode::event(QEvent *event)
    {
        if (event->type() == QEvent::NativeGesture) {
         qDebug() << event;
        }
    }
    

    I get

    QNativeGestureEvent(ZoomNativeGesture, localPos=714.98,31.1211, value=0.0039978)
    QNativeGestureEvent(ZoomNativeGesture, localPos=714.98,31.1211, value=0.0139923)
    QNativeGestureEvent(RotateNativeGesture, localPos=714.98,31.1211, value=-0.619853)
    QNativeGestureEvent(EndNativeGesture, localPos=714.98,31.1211, value=0)
    

    how do I get the value?



  • Solved it by doing this

            qDebug() << static_cast<QNativeGestureEvent*>(event)->value();
    

    So now I can get value, position, gesture and so on.



  • Not solved, nothing in the program works when I do

    bool ZoomCode::event(QEvent *event)
    {
        if (event->type() == QEvent::NativeGesture) {
            qreal value = static_cast<QNativeGestureEvent*>(event)->value();
    
            if(value > 0) {
                textEdit->zoomIn(value);
            } else if(value < 0) {
                textEdit->zoomOut(value);
            }
        }
    
    }
    

    Even when I only have the event(...) function and nothing inside it the program doesn't work. With doesn't work I mean I am not able to press buttons or scroll / edit the QTextEdit...


  • Lifetime Qt Champion

    @legitnameyo
    Hi when you do not use the event, you should forward it to base so other features can still work

    bool ZoomCode::event(QEvent *event)
    {
        if (event->type() == QEvent::NativeGesture) {
            qreal value = static_cast<QNativeGestureEvent*>(event)->value();
    
            if(value > 0) {
                textEdit->zoomIn(value);
            } else if(value < 0) {
                textEdit->zoomOut(value);
            }
        } else
      QWidget::event(event); // forward 
    
    }
    


  • Fixed it by doing as @mrjj said and also adding "return true" inside the if statement (at the end)

    Edit: the text does NOT zoom in our out. The zoomIn and zoomOut is called but does not do anything. I read on the docs that "Note: Zooming into HTML documents only works if the font-size is not set to a fixed size." Might that be the reason it won't zoom?



  • I had to utilize another method to zoom the text in my QTextEdit since zoomIn and zoomOut does not work for me. I did the following

    if(value > 0) {
                QTextCursor cursor = textEdit->textCursor();
                textEdit->selectAll();
                textEdit->setFontPointSize(textEdit->fontPointSize()*(1 + value));
                textEdit->setTextCursor( cursor );
                textEdit->zoomIn(5);
            } else if(value < 0) {
                QTextCursor cursor = textEdit->textCursor();
                textEdit->selectAll();
                textEdit->setFontPointSize(textEdit->fontPointSize()*(1 + value));
                textEdit->setTextCursor( cursor );
                textEdit->zoomOut(-5);
            }
    

    to scale the text.



  • Still not solved... Realized now that if I style certain parts of the text with a font size, that font size will get undone and set to the font size of every other character when I do this. The zoom destroys my formatting... I still can't get zoomIn and zoomOut to work no matter what I try and there is very little documentation on it as well.

    the Image Gesture Example uses another function to actually scale and not zoom, so looking at that example won't work now either...

    Edit: I know the zoomIn and zoomOut functions work because I created a new project, added a QTextEdit and zoomed in by 50x and it worked. I don't set the font of the QTextEdit to anything specific anywhere in my original project code...



  • The zoom works when I create new blank QTextEdit's but when I do the following

    QFile file("/Users/user/documents/saved_qtextedit_text.txt");
    
            if (file.open(QFile::ReadOnly | QFile::Text)) {
               textEdit->setHtml(file.readAll());
            }
    

    the zoom stops working

    Edit: Even adding the source code of zoom does not work (https://code.woboq.org/qt5/qtbase/src/widgets/widgets/qtextedit.cpp.html#_ZN9QTextEdit7zoomInFEf):

    bool ZoomCode::gestureEvent(QNativeGestureEvent *e) {
        float value = static_cast<float>(e->value());
    
        if(1) { // redundant
            qDebug() << "ZOOMING!"; // gets called so the program gets here
            QFont f = font();
            const float newSize = f.pointSizeF() + value;
            f.setPointSizeF(newSize);
            setFont(f);
    
           // does not work with textEdit->setFont(f); either
    
            //textEdit->zoomIn(20);
        }
    


  • The following partially works and I post in the hopes that someone might get an idea that will fix my issue :)

    bool ZoomCode::event(QEvent *event)
    {
        if (event->type() == QEvent::NativeGesture) {
            return gestureEvent(static_cast<QNativeGestureEvent*>(event));
        }
        return QWidget::event(event);
    }
    
    bool ZoomCode::gestureEvent(QNativeGestureEvent *e) {
        float value = e->value();
    
        textEdit->setFontPointSize(NULL); // zoom does not work without this
        textEdit->selectAll(); // some part of the text has to be selected before the zoom in the text starts to work. It does NOT matter if it is the WHOLE text or just a character in the text, just as long as something gets highlighted. Afterwards, nothing has to be highlighted again for the zoom to work. The zoom works on the whole text, no matter what part has been highlighted.
    
        if(value >0) {
              zoomIn(value + 5); // + 5 to add some zoom strength
        } else if(value < 0)
            zoomOut(value - 5); // -5 to add some zoom strength
        }
    }
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.