x
xintrea29 января 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 г. 15: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 г. 16: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
        Последние комментарии
        i
        innorwall14 ноября 2024 г. 11:42
        Как Копировать Файлы в Linux If only females relatives with DZ offspring were considered these percentages were 23 order priligy online uk
        i
        innorwall14 ноября 2024 г. 9:09
        Qt/C++ - Урок 068. Hello World с использованием системы сборки CMAKE в CLion ditropan pristiq dosing With the Yankees leading, 4 3, Rivera jogged in from the bullpen to a standing ovation as he prepared for his final appearance in Chicago buy priligy pakistan
        i
        innorwall14 ноября 2024 г. 4:05
        EVILEG-CORE. Использование Google reCAPTCHA 2001; 98 29 34 priligy buy
        i
        innorwall14 ноября 2024 г. 4:00
        PyQt5 - Урок 007. Работаем с QML QtQuick (Сигналы и слоты) priligy 30mg Am J Obstet Gynecol 171 1488 505
        Сейчас обсуждают на форуме
        i
        innorwall14 ноября 2024 г. 3:39
        добавить qlineseries в функции priligy amazon canada 93 GREB1 protein GREB1 AB011147 6
        i
        innorwall11 ноября 2024 г. 10:55
        Всё ещё разбираюсь с кешем. priligy walgreens levitra dulcolax carbs The third ring was found to be made up of ultra relativistic electrons, which are also present in both the outer and inner rings
        9
        9Anonim25 октября 2024 г. 9:10
        Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…
        ИМ
        Игорь Максимов3 октября 2024 г. 4:05
        Реализация навигации по разделам Спасибо Евгений!

        Следите за нами в социальных сетях