x
xintreaҚаң. 29, 2018, 11:12 Т.Ж.

Как изменить размер элемента после трансформации Scale?

Scale, transform

В QML есть такая проблема. Если элемент смасштабировать, то по-сути смасштабируется только его графическое представление, а, например его свойства width и height останутся прежними. С этим я более-менее разобрался:

https://webhamster.ru/mytetrashare/index/mtb0/1516351538jyd6u91xdf

Но все же хотелось бы, чтобы при масштабировании размеры объекта width и height тоже менялись. Я, например, сейчас пытаюсь разместить смасштабированные (уменьшенные) объекты на GridLayout, и не могу это толком сделать, потому что их width и height остались прежними. И GridLayout резервирует под них место так, как если бы они были не смасштабированы. Те же самые проблемы возникают и при выравнивании: выравниваются несмасштабированные прямоугольники элементов.

Я пытаюсь задать width и height вручную, с учетом масштаба, но тогда происходит что-то странное: некоторые подэлементы исчезают, MouseArea, развернутое на весь элемент, не обрабатывается.

В общем, никак не могу решить эту проблему.

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!

3
Виталий Антипов
  • Қаң. 29, 2018, 12:18 Т.Қ.

Я с GridLayout не работал, но возможно здесь ответ на часть ваших вопросов http://doc.qt.io/qt-5/qtquicklayouts-overview.html

    Виталий Антипов
    • Қаң. 29, 2018, 3:26 Т.Қ.
    • (өңделген)

    Проникся я вашей проблемой... Вот то ли я тупой, то ли разработчик ленивый. В общем сделал GridLayout из трех прямоугольников в одну строку. При клике на любой из них он должен уменьшиться в масштабе и вращаться вокруг своего центра. Вот код:

    import QtQuick 2.9
    import QtQuick.Window 2.2
    import QtQuick.Layouts 1.2
    
    Window {
        id: window
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
        GridLayout {
            id: grid
            anchors.fill: parent
            columnSpacing: 0
            Rectangle {
                    id: plate
                    Layout.leftMargin: (Layout.preferredWidth - Layout.preferredWidth*scale.xScale)/2 //это свойство автоматом для остальных Rectangle
                    Layout.topMargin: Layout.preferredHeight - Layout.preferredHeight*scale.yScale
                    Layout.preferredHeight: Layout.preferredWidth/2
                    Layout.preferredWidth: window.width/3
                    color: "lightblue"
                    transform: [
                        Rotation {
                            id: rot
                            origin.x: plate.width/2
                            origin.y: plate.height/2
                            angle: 0
                            NumberAnimation on angle {
                                id: na
                                running: false
                                loops: Animation.Infinite
                                from: 0; to: 360
                                duration: 3000
                            }
                        },
                        Scale {
                            id: scale
                            xScale: 1
                            yScale: 1
                        }
                    ]
                    MouseArea {
                        anchors.fill: parent
                        onClicked: {
                            na.running = true
                            scale.xScale = 0.5
                            scale.yScale = 0.5
                        }
                    }
                }
            Rectangle {
                    id: plate2
                    Layout.topMargin: Layout.preferredHeight - Layout.preferredHeight*scale2.yScale
                    Layout.preferredHeight: Layout.preferredWidth/2
                    Layout.preferredWidth: window.width/3
                    color: "lightgreen"
                    transform: [
                        Rotation {
                            id: rot2
                            origin.x: plate2.width/2
                            origin.y: plate2.height/2
                            angle: 0
                            NumberAnimation on angle {
                                id: na2
                                running: false
                                loops: Animation.Infinite
                                from: 0; to: 360
                                duration: 3000
                            }
                        },
                        Scale {
                            id: scale2
                            xScale: 1
                            yScale: 1
                        }
                    ]
                    MouseArea {
                        anchors.fill: parent
                        onClicked: {
                            na2.running = true
                            scale2.xScale = 0.5
                            scale2.yScale = 0.5
                        }
                    }
                }
            Rectangle {
                    id: plate3
                    Layout.topMargin: Layout.preferredHeight - Layout.preferredHeight*scale3.yScale
                    Layout.preferredHeight: Layout.preferredWidth/2
                    Layout.preferredWidth: window.width/3
                    color: "tomato"
                    transform: [
                        Rotation {
                            id: rot3
                            origin.x: plate3.width/2
                            origin.y: plate3.height/2
                            angle: 0
                            NumberAnimation on angle {
                                id: na3
                                running: false
                                loops: Animation.Infinite
                                from: 0; to: 360
                                duration: 3000
                            }
                        },
                        Scale {
                            id: scale3
                            xScale: 1
                            yScale: 1
                        }
                    ]
                    MouseArea {
                        anchors.fill: parent
                        onClicked: {
                            na3.running = true
                            scale3.xScale = 0.5
                            scale3.yScale = 0.5
                        }
                    }
                }
    }
    }
    А теперь по существу. Если я в свойствах изначально задаю x и y, то это координаты относительно элемента грида. Но если я по событию его присвою, то оно становится относительно самого грида. А мне же нужно управлять расположением внутри элемента при масштабировании! Anchors.CenterIn, horizontalCenter, verticalCenter относительно мифического Layout не действуют. Единственное что влияет на положение внутри элемента, так это отступы. И вот тут какой-то баг. Layout.topMargin надо задавать для каждого элемента отдельно, а Layout.leftMargin достаточно задать для одного из элементов и этот отступ будет действовать на все. И при клике происходит сдвиг всех. Криво реализовано. Я бы искал другой путь решения задачи, от GridView до группы Rectangle.
      Evgenii Legotckoi
      • Қаң. 29, 2018, 4:01 Т.Қ.

      Вообще, я бы отказался от GridLayout вовсе. Тут скорее больше подойдёт абсолютное позиционирование с расчётом размеров от ширины и высоты экрана или области размещения объектов.
      Как я понимаю топикстартер пишет что-то вроде просмоторщика изображений. Когда начнётся обработка Drug and Drop этих изображений, то тут вообще веселуха будет. Все те решения, которые мне попадались с GridLayout больше на костыли похожи были, хотя может в последних версиях Qt что-то и изменилось и я не в курсе актуальных изменений.


      А вообще в большинстве случаев пытаться задавать ширину и высоту через width и height для объекта, когда он находится внутри размещения (RowLayout, ColumnLayout, GridLayout) бесполезно. Эти параметры задаются через attach property Layout.
      То есть как у вас сделано через Layout.prefferedWidth и т.д. Через эти свойства можно указать некоторые параметры размеров и отступы от внутренних направляющих. Но не все возможные варианты можно реализовать к сожалению.

      Что касается работы scale и т.д. То тут есть некоторый нюанс с координатной системой. Каждый графический Item (не забываем, что всё наследовано от QQuitkItem в итоге, кроме некоторых особых реализаций) имеет отношение к координатной системе родительского объекта, а также свою собственную координатную систему. Так вот в его внутренней координатной системе и происходит вся отрисовка. И если вы делаете масштабирование, то масштабируется его внутренняя координатная система со всеми отрисованными внутри объектами. С этой точкой зрения с некоторым упрощением можно допустить, что каждый графический Item - это маленькая графическая сцена. Области отрисовки графической сцены тогда остаётся таже самая, а вот содержимое изменяет масштаб.

      Что касается абсолютного позиционирования, то гляньте эту статью . Там используется матрица с указанием указателей (id) на объекты. И через всю эту обвязку сделано расположение объектов.

        Пікірлер

        Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
        Кіріңіз немесе Тіркеліңіз
        AD

        C++ - Тест 004. Указатели, Массивы и Циклы

        • Нәтиже:50ұпай,
        • Бағалау ұпайлары-4
        m
        • molni99
        • Қаз. 26, 2024, 1:37 Т.Ж.

        C++ - Тест 004. Указатели, Массивы и Циклы

        • Нәтиже:80ұпай,
        • Бағалау ұпайлары4
        m
        • molni99
        • Қаз. 26, 2024, 1:29 Т.Ж.

        C++ - Тест 004. Указатели, Массивы и Циклы

        • Нәтиже:20ұпай,
        • Бағалау ұпайлары-10
        Соңғы пікірлер
        ИМ
        Игорь МаксимовҚар. 22, 2024, 11:51 Т.Ж.
        Django - Оқулық 017. Теңшелген Django кіру беті Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
        Evgenii Legotckoi
        Evgenii LegotckoiҚаз. 31, 2024, 2:37 Т.Қ.
        Django - Сабақ 064. Python Markdown кеңейтімін қалай жазуға болады Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
        A
        ALO1ZEҚаз. 19, 2024, 8:19 Т.Ж.
        Qt Creator көмегімен fb3 файл оқу құралы Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
        ИМ
        Игорь МаксимовҚаз. 5, 2024, 7:51 Т.Ж.
        Django - Сабақ 064. Python Markdown кеңейтімін қалай жазуға болады Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
        d
        dblas5Шілде 5, 2024, 11:02 Т.Ж.
        QML - Сабақ 016. SQLite деректер қоры және онымен QML Qt-та жұмыс істеу Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
        Енді форумда талқылаңыз
        m
        moogoҚар. 22, 2024, 7:17 Т.Ж.
        Mosquito Spray System Effective Mosquito Systems for Backyard | Eco-Friendly Misting Control Device & Repellent Spray - Moogo ; Upgrade your backyard with our mosquito-repellent device! Our misters conce…
        Evgenii Legotckoi
        Evgenii LegotckoiМаусым 24, 2024, 3:11 Т.Қ.
        добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
        t
        tonypeachey1Қар. 15, 2024, 6:04 Т.Ж.
        google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
        NSProject
        NSProjectМаусым 4, 2022, 3:49 Т.Ж.
        Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…

        Бізді әлеуметтік желілерде бақылаңыз