7

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).

MusiGenesis
  • 74,184
  • 40
  • 190
  • 334
  • 1
    this is a lot of code to re-code and reproduce, it'd be helpful if you can post a minimal working example. If I understood you corrently, I suggest using a 1 liner text input and not `TextArea`. Since it's read-only, use `Label` or r/o `TextInput` – bardao Sep 27 '18 at 20:45
  • @bardao Well, the text I need to display is multi-line and includes HTML. I was previously using a `Label` here, but it does not handle word-wrapping correctly when the HTML includes `` tags (this may be a since-fixed Qt bug, since I am stuck using Qt 5.6). – MusiGenesis Sep 27 '18 at 21:16
  • @MusiGenesis You should point this out in your question so that other users do not give you that kind of alternative solutions :-) – eyllanesc Sep 27 '18 at 21:18
  • would this work for you then? `flickableItem.enabled: false` property of `TextArea` – bardao Sep 27 '18 at 23:29

2 Answers2

3

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.

MusiGenesis
  • 74,184
  • 40
  • 190
  • 334
0

Try this out:

import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Controls 1.3

Window {
    visible: true
    width: 400
    height: 200

    TextArea {
        id: text
        anchors.fill: parent

        text: "Current\ntext\n\\to\nmove\ndown\ndown\ndown
               \ndown\ndown\ndown\ndown\ndown\ndown\ndown"

        flickableItem.interactive: false
    }
}

TextArea has flickableItem.enabled property. Since you're stuck with !t 5.6 this should work for you.

EDIT: changed to flickableItem.interactive instead.

bardao
  • 914
  • 12
  • 23
  • Well, this does prevent the TextArea from capturing the mouse wheel event, but it also prevents the `onLinkActivated` handler from firing. It's effectively equivalent to setting the TextArea's enabled to false (it may be literally equivalent too, I dunno). My problem is I specifically need to ignore the mouse wheel but not ignore the clicks. – MusiGenesis Sep 28 '18 at 00:40
  • you're right I just thought about it, the `flickableItem` is actually the `TextArea` :'D well that was fun – bardao Sep 28 '18 at 01:01
  • @MusiGenesis how about `flickableItem.interactive: false ` – bardao Sep 28 '18 at 01:03
  • you can basically access all the `Flickable` properties. check here http://doc.qt.io/qt-5/qml-qtquick-flickable.html see if any of those can help you solve the issue – bardao Sep 28 '18 at 01:04