common way to sort code?
-
I have reached line 1000 in my qml code.
there are a lot of redundant objects.
e.g.
Rectangle
Rectangle
Rectangle
etc....
i found a way to make additional qml files and load them in main.qml. so i have a better overview of the different interface elements etc....
is this the common way to sort large codes in qml? -
I have reached line 1000 in my qml code.
there are a lot of redundant objects.
e.g.
Rectangle
Rectangle
Rectangle
etc....
i found a way to make additional qml files and load them in main.qml. so i have a better overview of the different interface elements etc....
is this the common way to sort large codes in qml?@MaStaSk I think your question is more about re-using the qml code to reduce boilerplate.
my common approach is something like this:
- qml_root
- components
- AppStyles.qml (defining all styles in one location)
- AppButton.qml (example component)
- AppScrollView.qml (example component)
- Fonts.qml (loading fonts I ship with my application)
- Icon.qml (example component)
- qmldir (defining singletons)
- ...
- views
- Dashboard.qml
- Settings.qml
- ...
- ...
- components
- main.qml
Where main.qml has e.g. a StackView to manage all page transitions of the application.
Here some sample code of one of my templates, maybe this helps you:Note: This is just my personal approach.
// AppStyles.qml import QtQuick 2.12 Item { property color colorAppBackground: "white" property int heightNavbar: 64 property int sizeNavbarIcon: 18 property color colorNavbarBackground: "blue" property color colorNavbarForeground: "#FFFFFF" property font fontNavbar: Qt.font({ "bold": false, "italic": false, "underline": false, "weight": Font.Normal, "pointSize": 18, "capitalization": Font.MixedCase }) property int spacingContainerX: 20 property int spacingContainerY: 15 property int spacingLarge: 20 // ... }
// AppButton.qml import QtQuick 2.12 import QtQuick.Controls 2.12 Button { id: control text: "" leftPadding: AppStyles.paddingButtonX rightPadding: AppStyles.paddingButtonX topPadding: AppStyles.paddingButtonY bottomPadding: AppStyles.paddingButtonY contentItem: Text { text: control.text font: control.font opacity: enabled ? 1.0 : AppStyles.opacityButtonDisabled color: AppStyles.colorButtonForeground horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter elide: Text.ElideRight } background: Rectangle { implicitWidth: 100 implicitHeight: 40 opacity: enabled ? 1.0 : AppStyles.opacityButtonDisabled color: control.down ? Qt.darker(AppStyles.colorButtonBackground, 1.1) : AppStyles.colorButtonBackground radius: AppStyles.radiusButton } }
// AppScrollView.qml import QtQuick 2.12 import QtQuick.Controls 2.12 ScrollView { id: scrollView contentWidth: availableWidth contentHeight: column.height + AppStyles.spacingContainerY clip: true // defaults children to be put into the Column default property alias _contentChildren: column.data property alias contentSpacing: column.spacing Column { id: column width: scrollView.contentWidth spacing: AppStyles.spacingLarge } }
// Fonts.qml pragma Singleton import QtQuick 2.12 Item { id: fonts property FontLoader fontAwesomeIcons: FontLoader { source: "qrc:/fonts/Fontawesome/Font Awesome 6 Pro-Light-300.otf" } property FontLoader fontAwesomeBrands: FontLoader { source: "qrc:/fonts/Fontawesome/Font Awesome 6 Brands-Regular-400.otf" } readonly property string icons: fonts.fontAwesomeIcons.name readonly property string brands: fonts.fontAwesomeBrands.name }
// Icon.qml import QtQuick 2.0 Text { id: icon property bool brand: false property alias symbol: icon.text property alias size: icon.font.pointSize width: size height: size horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter font.family: brand ? Fonts.brands : Fonts.icons }
// qmldir singleton Fonts 1.0 Fonts.qml singleton AppStyles 1.0 AppStyles.qml
// e.g. in any qml page // removes all the boilerplate of the components AppScrollView { anchors.fill: parent anchors.margins: 20 AppButton { text: "Hello" onClicked: console.debug("hello button clicked") } RowLayout { Icon { symbol: "cog" } Text { text: qsTr("Settings") } } }
- qml_root
-
@MaStaSk I think your question is more about re-using the qml code to reduce boilerplate.
my common approach is something like this:
- qml_root
- components
- AppStyles.qml (defining all styles in one location)
- AppButton.qml (example component)
- AppScrollView.qml (example component)
- Fonts.qml (loading fonts I ship with my application)
- Icon.qml (example component)
- qmldir (defining singletons)
- ...
- views
- Dashboard.qml
- Settings.qml
- ...
- ...
- components
- main.qml
Where main.qml has e.g. a StackView to manage all page transitions of the application.
Here some sample code of one of my templates, maybe this helps you:Note: This is just my personal approach.
// AppStyles.qml import QtQuick 2.12 Item { property color colorAppBackground: "white" property int heightNavbar: 64 property int sizeNavbarIcon: 18 property color colorNavbarBackground: "blue" property color colorNavbarForeground: "#FFFFFF" property font fontNavbar: Qt.font({ "bold": false, "italic": false, "underline": false, "weight": Font.Normal, "pointSize": 18, "capitalization": Font.MixedCase }) property int spacingContainerX: 20 property int spacingContainerY: 15 property int spacingLarge: 20 // ... }
// AppButton.qml import QtQuick 2.12 import QtQuick.Controls 2.12 Button { id: control text: "" leftPadding: AppStyles.paddingButtonX rightPadding: AppStyles.paddingButtonX topPadding: AppStyles.paddingButtonY bottomPadding: AppStyles.paddingButtonY contentItem: Text { text: control.text font: control.font opacity: enabled ? 1.0 : AppStyles.opacityButtonDisabled color: AppStyles.colorButtonForeground horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter elide: Text.ElideRight } background: Rectangle { implicitWidth: 100 implicitHeight: 40 opacity: enabled ? 1.0 : AppStyles.opacityButtonDisabled color: control.down ? Qt.darker(AppStyles.colorButtonBackground, 1.1) : AppStyles.colorButtonBackground radius: AppStyles.radiusButton } }
// AppScrollView.qml import QtQuick 2.12 import QtQuick.Controls 2.12 ScrollView { id: scrollView contentWidth: availableWidth contentHeight: column.height + AppStyles.spacingContainerY clip: true // defaults children to be put into the Column default property alias _contentChildren: column.data property alias contentSpacing: column.spacing Column { id: column width: scrollView.contentWidth spacing: AppStyles.spacingLarge } }
// Fonts.qml pragma Singleton import QtQuick 2.12 Item { id: fonts property FontLoader fontAwesomeIcons: FontLoader { source: "qrc:/fonts/Fontawesome/Font Awesome 6 Pro-Light-300.otf" } property FontLoader fontAwesomeBrands: FontLoader { source: "qrc:/fonts/Fontawesome/Font Awesome 6 Brands-Regular-400.otf" } readonly property string icons: fonts.fontAwesomeIcons.name readonly property string brands: fonts.fontAwesomeBrands.name }
// Icon.qml import QtQuick 2.0 Text { id: icon property bool brand: false property alias symbol: icon.text property alias size: icon.font.pointSize width: size height: size horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter font.family: brand ? Fonts.brands : Fonts.icons }
// qmldir singleton Fonts 1.0 Fonts.qml singleton AppStyles 1.0 AppStyles.qml
// e.g. in any qml page // removes all the boilerplate of the components AppScrollView { anchors.fill: parent anchors.margins: 20 AppButton { text: "Hello" onClicked: console.debug("hello button clicked") } RowLayout { Icon { symbol: "cog" } Text { text: qsTr("Settings") } } }
@lemons said in common way to sort code?:
symbol: "cog"
Not related to OP's question but are you sure this works? AFAIK you'll need a mapping to map from a FA icon name to it's Unicode character
- qml_root
-
@lemons said in common way to sort code?:
symbol: "cog"
Not related to OP's question but are you sure this works? AFAIK you'll need a mapping to map from a FA icon name to it's Unicode character
@GrecKo I am using this all the time. As long as you have a ligature font, this works.
The FontAwesome Pro fonts have ligatures (named icons).
I also converted FeatherIcons to a ligature font (renaming the "x" icon to "times" as a ligature must have at least 2 characters) and this works as well.The easiest way to convert an icon set to a ligature font is to use tools like icomoon.io.
But there are also plenty of github projects that convert a directory with SVGs to a ligature font. -
@GrecKo I am using this all the time. As long as you have a ligature font, this works.
The FontAwesome Pro fonts have ligatures (named icons).
I also converted FeatherIcons to a ligature font (renaming the "x" icon to "times" as a ligature must have at least 2 characters) and this works as well.The easiest way to convert an icon set to a ligature font is to use tools like icomoon.io.
But there are also plenty of github projects that convert a directory with SVGs to a ligature font.@lemons good to know, I didn't realize ligatures could do this but it makes sense.
I use fontello.com to generate icon fonts because of its API, I don't think it supports ligature but I generate a mapping between the name of the icon and it's unicode character at compile time anyway
-
@MaStaSk I think your question is more about re-using the qml code to reduce boilerplate.
my common approach is something like this:
- qml_root
- components
- AppStyles.qml (defining all styles in one location)
- AppButton.qml (example component)
- AppScrollView.qml (example component)
- Fonts.qml (loading fonts I ship with my application)
- Icon.qml (example component)
- qmldir (defining singletons)
- ...
- views
- Dashboard.qml
- Settings.qml
- ...
- ...
- components
- main.qml
Where main.qml has e.g. a StackView to manage all page transitions of the application.
Here some sample code of one of my templates, maybe this helps you:Note: This is just my personal approach.
// AppStyles.qml import QtQuick 2.12 Item { property color colorAppBackground: "white" property int heightNavbar: 64 property int sizeNavbarIcon: 18 property color colorNavbarBackground: "blue" property color colorNavbarForeground: "#FFFFFF" property font fontNavbar: Qt.font({ "bold": false, "italic": false, "underline": false, "weight": Font.Normal, "pointSize": 18, "capitalization": Font.MixedCase }) property int spacingContainerX: 20 property int spacingContainerY: 15 property int spacingLarge: 20 // ... }
// AppButton.qml import QtQuick 2.12 import QtQuick.Controls 2.12 Button { id: control text: "" leftPadding: AppStyles.paddingButtonX rightPadding: AppStyles.paddingButtonX topPadding: AppStyles.paddingButtonY bottomPadding: AppStyles.paddingButtonY contentItem: Text { text: control.text font: control.font opacity: enabled ? 1.0 : AppStyles.opacityButtonDisabled color: AppStyles.colorButtonForeground horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter elide: Text.ElideRight } background: Rectangle { implicitWidth: 100 implicitHeight: 40 opacity: enabled ? 1.0 : AppStyles.opacityButtonDisabled color: control.down ? Qt.darker(AppStyles.colorButtonBackground, 1.1) : AppStyles.colorButtonBackground radius: AppStyles.radiusButton } }
// AppScrollView.qml import QtQuick 2.12 import QtQuick.Controls 2.12 ScrollView { id: scrollView contentWidth: availableWidth contentHeight: column.height + AppStyles.spacingContainerY clip: true // defaults children to be put into the Column default property alias _contentChildren: column.data property alias contentSpacing: column.spacing Column { id: column width: scrollView.contentWidth spacing: AppStyles.spacingLarge } }
// Fonts.qml pragma Singleton import QtQuick 2.12 Item { id: fonts property FontLoader fontAwesomeIcons: FontLoader { source: "qrc:/fonts/Fontawesome/Font Awesome 6 Pro-Light-300.otf" } property FontLoader fontAwesomeBrands: FontLoader { source: "qrc:/fonts/Fontawesome/Font Awesome 6 Brands-Regular-400.otf" } readonly property string icons: fonts.fontAwesomeIcons.name readonly property string brands: fonts.fontAwesomeBrands.name }
// Icon.qml import QtQuick 2.0 Text { id: icon property bool brand: false property alias symbol: icon.text property alias size: icon.font.pointSize width: size height: size horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter font.family: brand ? Fonts.brands : Fonts.icons }
// qmldir singleton Fonts 1.0 Fonts.qml singleton AppStyles 1.0 AppStyles.qml
// e.g. in any qml page // removes all the boilerplate of the components AppScrollView { anchors.fill: parent anchors.margins: 20 AppButton { text: "Hello" onClicked: console.debug("hello button clicked") } RowLayout { Icon { symbol: "cog" } Text { text: qsTr("Settings") } } }
@lemons thank you for providing your stuff. that helped me for a better orientation of my projects.
e.g. : main.qml:import QtQuick 2.15 import QtQuick.Window 2.15 Window { Timers { id: timerZoom } }
Timers.qml
import QtQuick 2.15 Timer { id: timerZoom interval: 10 repeat: true running: true onTriggered: { viewOne.scale += 0.0005 } }
now i can access e.g. timerZoom.running etc...
but if i add a second Timer with another id: timerSlide in Timers.qml i dont get access over another qml file (e.g. main.qml). it works just with one id?!
e.g. :
Timers2.qml:Timer { id: timerSlide interval: 20000 // 2 secs = 2000 repeat:true running: true onTriggered: { vars.currentIndex = (vars.currentIndex + 1) % folderModel.count vars.randomNumber = Math.floor(Math.random() * folderModel.count); viewOne.scale = 1 viewOne.rotation = 0 } } Timer { id: timerZoom interval: 10 repeat: true running: true onTriggered: { viewOne.scale += 0.0005 } }
or e.g. Timers3.qml:
import QtQuick 2.15 Item { /////////////TIMER//////////// Timer { id: timerSlide interval: 20000 // 2 secs = 2000 repeat:true running: true onTriggered: { vars.currentIndex = (vars.currentIndex + 1) % folderModel.count vars.randomNumber = Math.floor(Math.random() * folderModel.count); viewOne.scale = 1 viewOne.rotation = 0 } } Timer { id: timerZoom interval: 10 repeat: true running: true onTriggered: { viewOne.scale += 0.0005 } } ///////////////////////////// }
in Timers2.qml and Timers3.qml i can only access one of the timers.
- qml_root
-
@lemons thank you for providing your stuff. that helped me for a better orientation of my projects.
e.g. : main.qml:import QtQuick 2.15 import QtQuick.Window 2.15 Window { Timers { id: timerZoom } }
Timers.qml
import QtQuick 2.15 Timer { id: timerZoom interval: 10 repeat: true running: true onTriggered: { viewOne.scale += 0.0005 } }
now i can access e.g. timerZoom.running etc...
but if i add a second Timer with another id: timerSlide in Timers.qml i dont get access over another qml file (e.g. main.qml). it works just with one id?!
e.g. :
Timers2.qml:Timer { id: timerSlide interval: 20000 // 2 secs = 2000 repeat:true running: true onTriggered: { vars.currentIndex = (vars.currentIndex + 1) % folderModel.count vars.randomNumber = Math.floor(Math.random() * folderModel.count); viewOne.scale = 1 viewOne.rotation = 0 } } Timer { id: timerZoom interval: 10 repeat: true running: true onTriggered: { viewOne.scale += 0.0005 } }
or e.g. Timers3.qml:
import QtQuick 2.15 Item { /////////////TIMER//////////// Timer { id: timerSlide interval: 20000 // 2 secs = 2000 repeat:true running: true onTriggered: { vars.currentIndex = (vars.currentIndex + 1) % folderModel.count vars.randomNumber = Math.floor(Math.random() * folderModel.count); viewOne.scale = 1 viewOne.rotation = 0 } } Timer { id: timerZoom interval: 10 repeat: true running: true onTriggered: { viewOne.scale += 0.0005 } } ///////////////////////////// }
in Timers2.qml and Timers3.qml i can only access one of the timers.
@MaStaSk you have to make each non-root item accessible by using an alias:
Item { property alias timerSlide: timerSlide property alias timerZoom: timerZoom Timer { id: timerSlide } Timer { id: timerZoom } }
personally, I would try to avoid timers as much as possible. try using animations/animators for such tasks.
e.g. ScaleAnimator