x
xintreaJan. 29, 2018, 11:12 a.m.

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

Scale, transform

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

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

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

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

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

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.

Do you like it? Share on social networks!

3
Виталий Антипов
  • Jan. 29, 2018, 12:18 p.m.

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

    Проникся я вашей проблемой... Вот то ли я тупой, то ли разработчик ленивый. В общем сделал 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.

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


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

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

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

        Comments

        Only authorized users can post comments.
        Please, Log in or Sign up
        AD

        C ++ - Test 004. Pointers, Arrays and Loops

        • Result:50points,
        • Rating points-4
        m

        C ++ - Test 004. Pointers, Arrays and Loops

        • Result:80points,
        • Rating points4
        m

        C ++ - Test 004. Pointers, Arrays and Loops

        • Result:20points,
        • Rating points-10
        Last comments
        Evgenii Legotckoi
        Evgenii LegotckoiNov. 1, 2024, 12:37 a.m.
        Django - Lesson 064. How to write a Python Markdown extension Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
        A
        ALO1ZEOct. 19, 2024, 6:19 p.m.
        Fb3 file reader on Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
        ИМ
        Игорь МаксимовOct. 5, 2024, 5:51 p.m.
        Django - Lesson 064. How to write a Python Markdown extension Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
        d
        dblas5July 5, 2024, 9:02 p.m.
        QML - Lesson 016. SQLite database and the working with it in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
        k
        kmssrFeb. 9, 2024, 5:43 a.m.
        Qt Linux - Lesson 001. Autorun Qt application under Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
        Now discuss on the forum
        m
        moogoNov. 22, 2024, 6:17 p.m.
        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 LegotckoiJune 25, 2024, 1:11 a.m.
        добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
        t
        tonypeachey1Nov. 15, 2024, 5:04 p.m.
        google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
        NSProject
        NSProjectJune 4, 2022, 1:49 p.m.
        Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…

        Follow us in social networks