Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I disable the mouse wheel for a TextArea without disabling the entire control?

I'm using a TextArea to display multi-line text with embedded <IMG ...> tags in the delegate for a ListView. I have it set to read-only (and not disabled) because I need hyperlinks in the text to be clickable so I need to make use of its onLinkActivated event handler. This is normally something that would call for a Label (which does not handle mouse wheel events), but a Label does not render line-breaks correctly when the text includes <IMG ...> tags in the HTML.

The problem I'm having is that a TextArea handles mouse wheel events even when it is read-only, so if the cursor happens to be over one of the visible TextArea controls, the ListView will not respond to mouse wheel events (and so it does not scroll). In other words, the TextArea is capturing the mouse wheel events and I want it to not do this.

I see in the docs that controls have a wheelEnabled: property, but TextArea does not seem to support this.

Update: here is a minimum code sample that demonstrates the problem:

import QtQuick.Controls 1.4 as Controls

Rectangle {

    id: test

    color: "white"
    width: 300
    anchors {
        left: parent.left
        top: parent.top
        bottom: parent.bottom
    }

    Controls.ScrollView {

        id: _scrollview

        anchors.fill: parent

        ListView {
            anchors.fill: parent
            model: 100

            delegate: Rectangle {
                id: tableRow
                width: test.width
                height: 50
                color: "yellow"

                TextArea {
                    width: test.width / 2
                    height: tableRow.height
                    readOnly: true
                    text: "Row # " + index
                }

            }

        }

    }

}

If you hold the mouse cursor over the right side of this listview (i.e. not over the TextArea control in the row), the mouse wheel works as expected. But if you hold the mouse cursor over the TextArea in any of the rows, the ListView will not scroll with the mouse wheel (because the readOnly TextView is capturing the events).

like image 376
MusiGenesis Avatar asked Sep 27 '18 20:09

MusiGenesis


1 Answers

This is actually pretty easy, too bad I wasted the bounty. All this requires is a MouseArea positioned over the TextArea like so:

MouseArea {
    anchors.fill: txtTester
    onPressed: {
        mouse.accepted = false
    }
    onReleased: {
        mouse.accepted = false
    }

    property int scrollValue: 15
    onWheel: {
        if (wheel.angleDelta.y < 0) {
            //make sure not to scroll too far
            if (!_scrollview.flickableItem.atYEnd)
                _scrollview.flickableItem.contentY += scrollValue
        }
        else {
            //make sure not to scroll too far
            if (!_scrollview.flickableItem.atYBeginning)
                _scrollview.flickableItem.contentY -= scrollValue
        }
    }
}

This ignores press and release events so clicking on hyperlinks in the TextArea still works, but it intercepts mouse wheel events and applies them to moving the ScrollView as if the TextArea were not there.

like image 164
MusiGenesis Avatar answered Oct 03 '22 01:10

MusiGenesis