QML - Dynamically swap the visibility/opacity between overlapping Text and TextArea

我的梦境 提交于 2019-12-11 07:40:04

问题


I want to have a widget in QML which has combination of the following behaviors:

1) Multi line edit 2) Auto scroll the content as and when I hit newline. (The content on top of the page keeps going up as and when I enter new content at the bottom) 3) Have a placeholder text functionality.

As far as I know, only Text and TextField are having placeholder text property and only TextArea is having a multi line edit plus auto scroll. But If there is any such widget with all the combinations then, my question “Dynamically swap the visibility/opacity between overlapping Text and TextArea “ would be invalid.

In case there is no such widget (I wonder why), I am thinking to have a rectangle which has both Text and TextArea overlapping and based on the below logic I want to have the visibility/opacity/focus on one of them:

If the Text Area is empty (0 characters), then have the Text in the foreground with focus and with the placeholder text “Enter some text”. But as soon as the user starts typing, the Text should lose the focus, opacity and go to background and the TextArea should gain the focus and come to the foreground and start accepting multi line input. Similarly, when TextArea is in the foreground and is empty (0 characters) and when the user click on any other widget outside my Rectangle, the Text should again gain the focus, come to the foreground and display the placeholder again.

I tried to get inspiration from this code, but failed miserably, it would be helpful if anyone can help me with a few lines of code or give me some pointers on how to solve this.


回答1:


You can implement placeholderText for TextArea the same way Qt does in TextField. The source can be found here: TextField.qml

When you remove all the comments and properties, you basically have a background and on top of that a MouseArea, the placeholderText Text and a TextInput. Since you need to have the placeholder visually below the TextArea, you must have a transparent background:

PlaceholderTextArea.qml

import QtQuick 2.3
import QtQuick.Controls 1.2

Rectangle {
    property alias placeholderText: placeholder.text

    id: background
    width: 640
    height: 480
    color: "#c0c0c0"

    Text {
        id: placeholder
        anchors.fill: parent
        renderType: Text.NativeRendering
        opacity: !textArea.text.length && !textArea.activeFocus ? 1 : 0
    }

    TextArea {
        id: textArea
        anchors.fill: parent
        backgroundVisible: false
    }
}

and use your component:

PlaceholderTextArea {
    placeholderText: qsTr("Hello World")
    anchors.fill: parent
}



回答2:


Here's an alternative implementation, that works a bit better for me:

import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4

Item
{
    property alias placeholderText: placeholder.text

    property bool __shouldShowPlaceholderText:
        !textArea.text.length && !textArea.activeFocus

    // This only exists to get at the default TextFieldStyle.placeholderTextColor
    // ...maybe there is a better way?
    TextField
    {
        visible: false
        style: TextFieldStyle
        {
            Component.onCompleted: placeholder.textColor = placeholderTextColor
        }
    }

    TextArea
    {
        id: placeholder
        anchors.fill: parent
        visible: __shouldShowPlaceholderText
        activeFocusOnTab: false
    }

    TextArea
    {
        id: textArea
        anchors.fill: parent
        backgroundVisible: !__shouldShowPlaceholderText
    }
}


来源:https://stackoverflow.com/questions/27088152/qml-dynamically-swap-the-visibility-opacity-between-overlapping-text-and-texta

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!