Как заставить TextArea иметь максимальный размер и полосу прокрутки? - PullRequest
0 голосов
/ 04 февраля 2019

У меня есть TextArea, который обычно будет содержать только одну строку текста.Однако я хочу, чтобы пользователь мог добавить больше, и TextArea можно увеличить до максимум 15 строк, после чего любой дополнительный текст будет доступен через полосу прокрутки.Я смог заставить аспект прокрутки работать, если TextArea содержаться в Flickable (что в конечном итоге содержится в Rectangle).

Rectangle {
    id: rec
    width: 200
    height: 25

    Flickable {
        id: flickable
        anchors.fill: parent
        contentWidth: textArea.width
        contentHeight: textArea.height

        TextArea.flickable:
            TextArea {
            id: textArea
            text: qsTr("Hello, world!")
            wrapMode: Text.WordWrap
        }
        ScrollBar.vertical: ScrollBar { }
    }
}

На данный момент, какя бы продолжил, чтобы текстовое поле расширялось текстом до некоторого предопределенного максимального числа пикселей (скажем, 300)?

Редактировать

Хорошо, почти тампросто одна проблема с правильным центрированием текста с помощью решения Митча.Мой main.qml файл содержит следующее:

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    HelloWorld{
        anchors.centerIn: parent
    }
}

Любой мой HelloWorld.qml файл содержит следующее:

import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import QtQuick.Dialogs 1.2
import QtQuick.Controls.Styles 1.4

ColumnLayout{

    width: 250

    FontMetrics {
        id: fontMetrics
        font: textArea.font
    }

    Flickable {
        id: flickable
        width: parent.width
        height: Math.min(contentHeight, fontMetrics.height * 15)
        contentWidth: width
        contentHeight: textArea.implicitHeight
        clip: true

        TextArea.flickable: TextArea {
            id: textArea
            text: "Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! "
                + "Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! "
            wrapMode: Text.WordWrap
            //padding: 0

            background: Rectangle {
                border.color: "blue"
            }
        }
        ScrollBar.vertical: ScrollBar {}
    }

}

Это очень близко к работе, но по той или иной причинекогда у меня есть этот код за пределами main.qml, текст смещается ниже и вправо, пока пользователь не выберет его:

enter image description here

После выборатекст выглядит следующим образом (именно с этого я и хочу начать): enter image description here

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

Установите height для Flickable равным contentHeight или 300 - в зависимости от того, что меньше:

import QtQuick 2.12
import QtQuick.Controls 2.12

ApplicationWindow {
    width: 400
    height: 400
    color: "#444"
    visible: true

    Rectangle {
        anchors.fill: flickable
    }

    Flickable {
        id: flickable
        width: parent.width
        height: Math.min(contentHeight, 300)
        contentWidth: width
        contentHeight: textArea.implicitHeight

        TextArea.flickable: TextArea {
            id: textArea
            text: qsTr("Hello, world! Hello, world! Hello, world! Hello, world! ")
            wrapMode: Text.WordWrap
        }
        ScrollBar.vertical: ScrollBar {}
    }
}

textarea

Если вы не хотите, чтобы Rectangle находился там, где он (брат Flickable), вы можете удалить его, добавив

clip: true

к Flickable и

*От 1020 *

до TextArea.

Также, если вы хотите быть немного более точным, вы можете использовать FontMetrics для вычисления высоты строки:

import QtQuick 2.12
import QtQuick.Controls 2.12

ApplicationWindow {
    width: 400
    height: 400
    color: "#444"
    visible: true

    FontMetrics {
        id: fontMetrics
        font: textArea.font
    }

    Flickable {
        id: flickable
        width: parent.width
        height: Math.min(contentHeight, fontMetrics.height * 15)
        contentWidth: width
        contentHeight: textArea.implicitHeight
        clip: true

        TextArea.flickable: TextArea {
            id: textArea
            text: "Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! "
                + "Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! "
            wrapMode: Text.WordWrap
            padding: 0

            background: Rectangle {}
        }
        ScrollBar.vertical: ScrollBar {}
    }
}
0 голосов
/ 05 февраля 2019

Aha!После долгих поисков я наконец нашел удобное свойство с именем paintedHeight, которое является частью TextArea.Это получит высоту текста в вашем TextArea, поэтому я использовал это, чтобы найти, что размер каждой строки равен 13, и просто обновлять высоту основы Rectangle всякий раз, когда текст редактируется, и просто ограничивать егоif заявление.Вот мое дурацкое решение:

Rectangle {
    property int paintedHeight: 13
    id: rec
    width: 200
    height: paintedHeight * 2

    Flickable {
        id: flickable
        anchors.fill: parent
        contentWidth: textArea.width
        contentHeight: textArea.height

        TextArea.flickable:
            TextArea {
            id: textArea
            wrapMode: Text.WordWrap

            property int maxNumberOfLines: 15
            onTextChanged: {
                rec.height = (lineCount * rec.paintedHeight) + rec.paintedHeight

                // cap the height so that the box stops expanding at maxNumberOfLines
                if(rec.height > rec.paintedHeight * (maxNumberOfLines + 1)){
                    rec.height = rec.paintedHeight * (maxNumberOfLines + 1)
                }
            }
        }
        ScrollBar.vertical: ScrollBar { }
    }
}

В случае, если кто-то еще окажется в подобной ситуации, просто выполните console.log(paintedHeight), чтобы получить высоту текущего текста (и разделите соответственно, если у вас более одной строки)чтобы получить высоту вашего текста, так как он может отличаться от моего в зависимости от стиля и шрифта, который вы используете (я использую стиль Fusion).Затем просто измените свойство paintedHeight в Rectangle, указав свой размер, а свойство maxNumberOfLines в TextArea, указав максимальное количество строк, которое должен иметь текст.

...