Размер изображения отличается после второго клика по нему

У меня есть следующий минимальный рабочий пример, взятый из моего текущего проекта:

import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.4

Window {
    visible: true

    width: Screen.width/2
    height: Screen.height/2

    property real ueMinOpacity: 0.00
    property real ueMaxOpacity: 1.00

    Rectangle {
        anchors.fill: parent
        anchors.margins: 8

        border.color: "#4682b4"
        radius: 16

        clip: true

        gradient: Gradient {
            GradientStop {
                position: 0
                color: "#ffffff"
            }   // GradientStop

            GradientStop {
                position: 1
                color: "#303030"
            }   // GradientStop
        }   // Gradient

        Rectangle {
            anchors.fill: parent
            antialiasing: true

            border.color: "#4682b4"
            border.width: 1

            radius: 16
            clip: true

            gradient: Gradient {
                GradientStop {
                    position: 0
                    color: "#ffffff"
                }   // GradientStop

                GradientStop {
                    position: 1
                    color: "#000000"
                }   // GradientStop
            }   // Gradient

            RowLayout {
                spacing: 8
                anchors.fill: parent

                TextField {
                    id: ueProductSearchTextField

                    antialiasing: true

                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    Layout.alignment: Qt.AlignLeft|Qt.AlignVCenter
                    Layout.margins: 8

                    placeholderText: qsTr("Enter product info")
                }   // TextField

                Rectangle {
                    id: ueImageWrapper

                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    Layout.alignment: Qt.AlignRight|Qt.AlignVCenter
                    Layout.margins: 8

                    antialiasing: true

                    border.color: "#4682b4"
                    border.width: 1

                    radius: 16
                    clip: true
                    visible: ueProductSearchTextField.length > 0

                    gradient: Gradient {
                        GradientStop {
                            position: 0
                            color: "#636363"
                        }   // GradientStop

                        GradientStop {
                            position: 1
                            color: "#303030"
                        }   // GradientStop
                    }   // Gradient

                    Image {
                        anchors.fill: parent

                        source: "http://www.clipartbest.com/cliparts/9iR/gEX/9iRgEXXxT.png"

                        antialiasing: true

                        clip: true

                        smooth: true

                        fillMode: Image.PreserveAspectFit

                        horizontalAlignment: Image.AlignHCenter
                        verticalAlignment: Image.AlignVCenter

                        sourceSize.width: 96
                        sourceSize.height: 96
                    }   // Image

                    MouseArea {
                        anchors.fill: parent
                        enabled: ueImageWrapper.visible

                        onClicked: {
                            ueProductSearchTextField.text="";
                        }   // onClicked
                    }   // MouseArea


                    onWidthChanged: {
                        print("ueImageWrapper.width:"+ueImageWrapper.width);
                    }   // onWidthChanged

                    onHeightChanged: {
                        print("ueImageWrapper.height:"+ueImageWrapper.height);
                    }   // onHeightChanged
                }   // Rectangle
            }   // RowLayout
        }   // Rectangle
    }   // Rectangle
}   // Window

Теперь целью этого Item/Rectangle является фильтрация записей базы данных в соответствии с введенным значением TextField, что отлично работает. Однако, как только текст TextField больше не пуст (когда пользователь вводит какую-то строку), справа от Layout Image для очистки текста отображается через OpacityAnimator. После запуска приложения я получаю следующий скриншот: значок открытого текста скрыт, так как в TextField нет текста: Скриншот запуска приложения Затем я ввожу текст в TextField и появится значок очистить текст: Tesxt ввел снимок экрана Затем, например, я очищаю текст, щелкнув значок очистить текст, и он (значок ) снова скрыт, что нормально:
Снимок экрана с очищенным текстом И, наконец, я повторно ввожу текст в TextField, значок очистить текст снова виден, но он имеет другое размер: введите описание изображения здесь Почему? Я не менял код. Должно быть какая-то проблема с Layouts, но я ее просто не вижу! Вот также вывод отладки обработчиков onWidthChanged и onHeightChanged:

qml: ueImageWrapper.width:37.56521739130435
qml: ueImageWrapper.height:480
qml: ueImageWrapper.width:132.92307692307693
qml: ueImageWrapper.width:133.8378378378/3784


person KernelPanic    schedule 18.01.2016    source источник


Ответы (1)


Предложение BaCaRoZzo работает, но я также немного не уверен, почему оно ведет себя именно так. Если взять более простой пример:

import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Layouts 1.0
import QtQuick.Controls 1.0

Window {
    visible: true
    width: 800
    height: 800

    Shortcut {
        sequence: "Ctrl+Q"
        onActivated: Qt.quit()
    }

    Item {
        id: boundary
        width: 400
        height: 400
        anchors.centerIn: parent

        RowLayout {
            anchors.fill: parent

            Rectangle {
                Layout.fillWidth: true
                Layout.fillHeight: true
                color: "steelblue"
            }

            Rectangle {
                id: rect
                Layout.fillWidth: true
                Layout.fillHeight: true
                color: "salmon"
                visible: false
            }
        }
    }

    Rectangle {
        anchors.fill: boundary
        color: "transparent"
        border.color: "black"
    }

    Button {
        text: "Toggle visibility"
        onClicked: rect.visible = !rect.visible
    }
}

Второй прямоугольник сначала невидим, а затем отображается/скрывается нажатием кнопки. Однако, когда он начинается как невидимый, он никогда не получает размер после отображения. С другой стороны, если он начинается видимым, то он занимает половину ширины макета.

Если вы внимательно прочитаете документацию, она не скажите, что необходимо установить preferredWidth/preferredHeight, если вы просто хотите, чтобы элемент заполнил доступное пространство. По этой причине кажется ошибкой то, как макеты обрабатывают первоначальную видимость своих элементов. Я бы предложил подать отчет об ошибке.

person Mitch    schedule 19.01.2016
comment
Спасибо за ответ. У меня не было времени проверить это сегодня. :) Мне тоже пахнет жуком! Однако установка preferredWidth/preferredHeight обычно имеет смысл. По крайней мере, если вы не хотите получить идеально разделенное пространство, как в этом случае. Надеюсь, кто-то может отправить отчет об ошибке. - person BaCaRoZzo; 19.01.2016
comment
Да, это имеет смысл, особенно если это не просто невидимая прокладка. - person Mitch; 19.01.2016