如何在不禁用整个控件的情况下禁用 TextArea 的鼠标滚轮?

Posted

技术标签:

【中文标题】如何在不禁用整个控件的情况下禁用 TextArea 的鼠标滚轮?【英文标题】:How can I disable the mouse wheel for a TextArea without disabling the entire control? 【发布时间】:2018-09-27 20:18:33 【问题描述】:

我正在使用TextAreaListView 的委托中显示带有嵌入<IMG ...> 标记的多行文本。我将其设置为只读(而不是禁用),因为我需要文本中的超链接是可点击的,所以我需要使用它的onLinkActivated 事件处理程序。这通常需要 Label(它不处理鼠标滚轮事件),但当文本在 html 中包含 <IMG ...> 标记时,Label 不会正确呈现换行符。

我遇到的问题是 TextArea 处理鼠标滚轮事件,即使它是只读的,所以如果光标恰好位于可见的 TextArea 控件之一上方,ListView 将不会响应鼠标滚轮事件(因此它不会滚动)。换句话说,TextArea 正在捕获鼠标滚轮事件,我希望它不要这样做。

我在文档中看到控件具有 wheelEnabled: 属性,但 TextArea 似乎不支持这一点。

更新:这是演示问题的最小代码示例:

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
                

            

        

    


如果您将鼠标光标悬停在此列表视图的右侧(即不在行中的 TextArea 控件上),鼠标滚轮将按预期工作。但是,如果您将鼠标光标悬停在任何行中的 TextArea 上,ListView 将不会随着鼠标滚轮滚动(因为 readOnly TextView 正在捕获事件)。

【问题讨论】:

这是需要重新编码和重现的大量代码,如果您可以发布一个最小的工作示例,将会很有帮助。如果我正确理解您,我建议使用 1 行文本输入而不是 TextArea。由于它是只读的,请使用 Label 或 r/o TextInput @bardao 好吧,我需要显示的文本是多行的,包括 HTML。我以前在这里使用Label,但是当HTML包含<IMG ...>标签时它不能正确处理自动换行(这可能是一个自修复的Qt错误,因为我一直在使用Qt 5.6)。 @MusiGenesis 你应该在你的问题中指出这一点,这样其他用户就不会给你那种替代解决方案:-) 那么这对你有用吗? flickableItem.enabled: falseTextArea 的属性 【参考方案1】:

这实际上很容易,可惜我浪费了赏金。所有这些都需要一个 MouseArea 定位在 TextArea 上,如下所示:

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
        
    

这会忽略按下和释放事件,因此单击TextArea 中的超链接仍然有效,但它会拦截鼠标滚轮事件并将它们应用于移动ScrollView,就好像TextArea 不存在一样。

【讨论】:

【参考方案2】:

试试这个:

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 具有 flickableItem.enabled 属性。由于您坚持使用 !t 5.6 这应该适合您。

编辑:改为flickableItem.interactive

【讨论】:

嗯,这确实阻止了 TextArea 捕获鼠标滚轮事件,但它也阻止了 onLinkActivated 处理程序的触发。它实际上等效于将 TextArea 的启用设置为 false(我不知道,它也可能实际上是等效的)。我的问题是我特别需要忽略鼠标滚轮而不是忽略点击。 你说得对,我只是想了一下,flickableItem 实际上是TextArea :'那很好玩 @MusiGenesis 怎么样flickableItem.interactive: false 您基本上可以访问所有Flickable 属性。在这里查看doc.qt.io/qt-5/qml-qtquick-flickable.html 看看是否有任何可以帮助您解决问题

以上是关于如何在不禁用整个控件的情况下禁用 TextArea 的鼠标滚轮?的主要内容,如果未能解决你的问题,请参考以下文章

Bootstrap modal : 在不禁用背景控件的情况下禁用背景点击关闭

如何在不像 Whatsapp 那样遮挡整个屏幕的情况下禁用表格视图?

WPF:如何在不禁用箭头键导航的情况下禁用选项卡导航?

在不锁定 UI 的情况下禁用滚动视图

如何在不禁用突出显示的情况下禁用合适的触摸行

如何在不使项目变灰的情况下禁用 UITabBarItem