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) на объекты. И через всю эту обвязку сделано расположение объектов.

        Пікірлер

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

        C++ - Тест 001. Первая программа и типы данных

        • Нәтиже:66ұпай,
        • Бағалау ұпайлары-1
        t

        C++ - Тест 001. Первая программа и типы данных

        • Нәтиже:33ұпай,
        • Бағалау ұпайлары-10
        t

        Qt - Тест 001. Сигналы и слоты

        • Нәтиже:52ұпай,
        • Бағалау ұпайлары-4
        Соңғы пікірлер
        G
        GoattRockҚыр. 3, 2024, 1:50 Т.Қ.
        Linux жүйесінде файлдарды қалай көшіруге болады Задумывались когда-нибудь о том, как мы привыкли доверять свои вещи службам грузоперевозок? Сейчас такие услуги стали неотъемлемой частью нашей жизни, особенно когда речь идет о переездах между …
        d
        dblas5Шілде 5, 2024, 11:02 Т.Ж.
        QML - Сабақ 016. SQLite деректер қоры және онымен QML Qt-та жұмыс істеу Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
        k
        kmssrАқп. 8, 2024, 6:43 Т.Қ.
        Qt Linux - Сабақ 001. Linux астында Autorun Qt қолданбасы как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
        АК
        Анатолий КононенкоАқп. 5, 2024, 1:50 Т.Ж.
        Qt WinAPI - Сабақ 007. Qt ішінде ICMP Ping арқылы жұмыс істеу Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
        Енді форумда талқылаңыз
        Evgenii Legotckoi
        Evgenii LegotckoiМаусым 24, 2024, 3:11 Т.Қ.
        добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
        F
        FynjyШілде 22, 2024, 4:15 Т.Ж.
        при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …
        BlinCT
        BlinCTМаусым 25, 2024, 1 Т.Ж.
        Нарисовать кривую в qml Всем привет. Имеется Лист листов с тосками, точки получаны интерполяцией Лагранжа. Вопрос, как этими точками нарисовать кривую? ChartView отпадает сразу, в qt6.7 появился новый элемент…
        BlinCT
        BlinCTМамыр 5, 2024, 5:46 Т.Ж.
        Написать свой GraphsView Всем привет. В Qt есть давольно старый обьект дял работы с графиками ChartsView и есть в 6.7 новый но очень сырой и со слабым функционалом GraphsView. По этой причине я хочу написать х…
        Evgenii Legotckoi
        Evgenii LegotckoiМамыр 2, 2024, 2:07 Т.Қ.
        Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Добрый день. По моему мнению - да, но то, что будет касаться вызовов к функционалу Андроида, может создать огромные трудности.

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