Top.Mail.Ru

Qt и QML. mtPaint3D. Создаем утилиту для 3D-рисования. День 9.

Завершающий день марафона по разработке графически-рисовательного приложения с Qt! Понадобилось ровно столько дней, сколько и было отмерено изначально ) При этом форсировать на промежуточных этапах не пришлось 👌 Вкратце расскажу, что я добавил для финальной на данный момент версии...

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

mtPaint3D - Paint3D в Qt.

Для добавления иконок выкидываем названия кнопок из соответствующих моделей и вместо них добавляем имена файлов, на примере ToolPanel:

Rectangle {
    id: rootRectangle
    color: "transparent"
    height: buttonsGrid.height

    property int selectedTool: PaintEntity.ToolType.Cuboid

    property var buttonsModel: [
        {iconFileName: "select.png", type: PaintEntity.ToolType.Select},
        {iconFileName: "delete.png", type: PaintEntity.ToolType.Delete},
        {iconFileName: "cuboid.png", type: PaintEntity.ToolType.Cuboid},
        {iconFileName: "sphere.png", type: PaintEntity.ToolType.Sphere},
        {iconFileName: "cone.png", type: PaintEntity.ToolType.Cone},
        {iconFileName: "cylinder.png", type: PaintEntity.ToolType.Cylinder},
        {iconFileName: "torus.png", type: PaintEntity.ToolType.Torus},
        {iconFileName: "extruded_text.png", type: PaintEntity.ToolType.ExtrudedText},
        {iconFileName: "curve.png", type: PaintEntity.ToolType.Curve},
        {iconFileName: "delete_all.png", type: PaintEntity.ToolType.DeleteAll}
    ]

// ...............

Соответственно, далее эти данные помещаем туда, где им и место:

Button {
	checkable: true
	width: (rootRectangle.width - (buttonsGrid.columns - 1) * buttonsGrid.spacing) / buttonsGrid.columns
	height: width

	icon.width: 0.8 * width
	icon.height: 0.8 * height
	icon.color: "transparent"
	icon.source: "../icons/tools/" + modelData['iconFileName']

	property var type: modelData['type']

// ...............

В принципе, все изменения относительно вчерашней версии и так видны на скрине ) Отчасти для получения полезной информации, отчасти ради большего оживления интерфейса я добавил окно с текущими параметрами и всплывающее сообщение при выборе или удалении объекта:

Информационное окно.

В подробности реализации не погружаемся, исходники будут там же, где и обычно 👍 Ах да, я еще добавил инструмент для удаления всех объектов. Вообще он мне не особо нужен, но расположив кнопки по пять в ряд, оказалось, что 9 кнопок на 5 нацело не делятся, поэтому и была добавлена 10-я, юбилейная:

Панель инструментов в QML.

Ну и при ее использовании происходит полная очистка сцены:

Кроме того, очевидно, что никак не обойтись без возможности сохранения и загрузки текущих объектов. Для этого добавились два диалоговых окна соответственно для сохранения и загрузки:

FileDialog {
	id: saveFileDialog
	title: qsTr("Save")
	defaultSuffix: qsTr("mtPaint3D")
	selectExisting: false

	onAccepted: {
		paintEntity.save(saveFileDialog.fileUrl);
	}
}

FileDialog {
	id: loadFileDialog
	title: qsTr("Load")
	nameFilters: [qsTr("*.mtPaint3D")]

	onAccepted: {
		paintEntity.load(loadFileDialog.fileUrl);
	}
}

В результате пользовательких действий происходит вызов save() или load() из PaintEntity. В целом же, механизм следующий... Для каждого из существующих на сцене PaintObject'ов вызывается метод save() , далее сохраняются последовательно базовые и уникальные параметры объектов - saveBasicData() и saveUniqueData(). В случае необходимости методы переопределяются в объектах, которые наследуют от PaintObject. Так для кривой Безье процесс сохранения и загрузки получился, в принципе, своим собственным. Для текста переопределяется только saveUniqueData() в силу наличия собственно текста, который также нужно подвергнуть сохранению.

Вот как-то так. Меня и результат, и процесс, и затраченное время полностью удовлетворили, надеюсь прочтение и отслеживание прогресса также несли в себе некие приятно-познавательные нотки 👍 А на этом завершаем, посмотрим, как зайдет данный формат, всем большое спасибо за внимание! )

Итоговый исходный код и проект: mtPaint3D

Подписаться
Уведомление о
guest
0 комментариев
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x