0

I am building a settings page for my app and to be efficient I created a component separately to use it in different files.

I am using this component in the settings and giving them each a different icon, text and color. Everything works fine except the icon.

I am using the following things:

  1. Ubuntu
  2. Qt Creator 9.0.2
  3. Qt 6.2.4

Component.qml

import QtQuick 2.15
import QtQuick.Layouts 1.15

Item {

    property alias option_width: menu_option_btn.width
    property alias btnText: btn_text.text
    property alias btnIcon: btn_icon.source
    property alias btnColor: bg_option.color
    property alias btnIconWidth: btn_icon.sourceSize.width
    property alias btnIconHeight: btn_icon.sourceSize.height

    id: menu_option_btn
    height: 50
    width: 300

    Rectangle {
        id: bg_option
        color: "#433f3f"
        anchors.fill: parent
    }

    MouseArea {
        id: mouseArea
        anchors.fill: parent

        RowLayout {
            id: btn_layout
            anchors.fill: parent

            Rectangle {
                id: image_holder
                width: 50
                height: 200
                color: "#0000ffff"
                Layout.maximumWidth: 50
                Layout.minimumWidth: 50
                Layout.fillHeight: true

                Image {
                    id: btn_icon
                    anchors.fill: parent
                    sourceSize.height: 52
                    sourceSize.width: 52
                    anchors.leftMargin: 2
                    anchors.bottomMargin: 5
                    anchors.topMargin: 5
                    fillMode: Image.PreserveAspectFit
                    visible: true
                }
            }

            Text {
                id: btn_text
                color: "#ffffff"
                text: qsTr("Text")
                font.pixelSize: 16
                Layout.leftMargin: 5
                Layout.fillWidth: true
            }
        }
    }


}

Settings.qml

import "../../widgets"
import QtQuick 2.15
import QtQuick.Layouts 6.0
import QtQuick.Controls 2.15

Item{
    id: settings_app
    width: 1024 ;height: 540

    /*
    Image {
        id: settings_bg
        anchors.fill: parent
        source: "../../wallpapers/sunset flowers.png"
        fillMode: Image.PreserveAspectCrop
    }

*/
    Component.onCompleted: {
        settingsApp.showName()
    }

    RowLayout {
        id: settings_layout
        anchors.fill: parent

        Rectangle {
            id: side_menu
            width: 200
            height: 200
            color: "#e82f2e2e"
            Layout.maximumWidth: 250
            Layout.minimumWidth: 250
            Layout.fillHeight: true

            ColumnLayout {
                id: side_menu_layout
                anchors.fill: parent
                spacing: 0

                ColumnLayout {
                    id: side_menu_layout_up
                    height: 100
                    Layout.alignment: Qt.AlignLeft | Qt.AlignTop
                    spacing: 0

                    Layout.maximumHeight: 200
                    Layout.minimumHeight: 200
                    Layout.fillWidth: true

                    Image {
                        id: frame_bg
                        width: 150
                        height: 150
                        opacity: 1
                        source: "../../icons/DSC04191.JPG"
                        Layout.maximumHeight: 150
                        Layout.maximumWidth: 150
                        Layout.minimumHeight: 150
                        Layout.minimumWidth: 150
                        Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
                        sourceSize.height: 150
                        sourceSize.width: 150
                        fillMode: Image.PreserveAspectCrop
                    }

                    Text {
                        id: displayName
                        color: "#ffffff"
                        text: qsTr("Username")
                        font.pixelSize: 16
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                        Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
                        Layout.fillWidth: true
                    }

                }

                ColumnLayout {
                    id: side_menu_down_layout
                    width: 100
                    height: 100
                    Layout.topMargin: 50
                    Layout.maximumWidth: 250
                    Layout.minimumWidth: 250
                    Layout.maximumHeight: 275
                    Layout.minimumHeight: 275
                    Layout.alignment: Qt.AlignLeft | Qt.AlignBottom
                    Layout.fillHeight: true
                    Layout.fillWidth: true

                    MenuOption {
                        id: option_account
                        Layout.leftMargin: 10
                        Layout.fillWidth: true
                        Layout.alignment: Qt.AlignLeft | Qt.AlignTop
                        btnText: "Account"
                        option_width: 250
                        btnColor: "#0000ffff"
                        btnIconHeight: 52
                        btnIconWidth: 52
                        btnIcon: "qrc:/Icons/icons/monitor.png"
                    }
                }
            }

        }
    }

    Connections{
        target: settingsApp

        function onChangeDisplayName(stringText){
            displayName.text = stringText
        }
    }

}

Here is my DIR tree

.
├── apps
│   ├── Settings
│   │   └── Settings.qml
│   └── VStore
│       ├── AppView.qml
│       ├── StoreAccount.qml
│       ├── StoreSettings.qml
│       └── VStore.qml
├── icons
│   ├── account.png
│   ├── back-arrow-64.png
│   ├── battery-icon.png
│   ├── cart.png
│   ├── cart-solo.png
│   ├── close.png
│   ├── devices.png
│   ├── DSC04191.JPG
│   ├── error.png
│   ├── icons8-devices-32.png
│   ├── info.png
│   ├── menu.png
│   ├── microphone-icon.png
│   ├── monitor.png
│   ├── notification-icon.png
│   ├── notification.png
│   ├── power-icon.png
│   ├── restart.png
│   ├── search.png
│   ├── settings-icon - app.png
│   ├── settings.png
│   ├── shutdown-menu.png
│   ├── shutdown.png
│   ├── star.png
│   ├── success.png
│   ├── user-icon.png
│   └── warning.png
├── rc_resources.py
├── resources.qrc
├── screens
│   ├── AppMenu.qml
│   ├── Desktop.qml
│   └── Login.qml
├── startup.py
├── system
│   ├── config
│   │   ├── endpoints.json
│   │   ├── package_list.txt
│   │   ├── sys_config.cpp
│   │   ├── sys_config.out
│   │   ├── syslogs.log
│   │   └── system.ini
│   ├── __pycache__
│   │   ├── user_auth.cpython-310.pyc
│   │   └── utils.cpython-310.pyc
│   ├── user_auth.py
│   └── utils.py
├── VultureOS.pyproject
├── VultureOS.pyproject.user
├── wallpapers
│   ├── cubes.jpg
│   └── sunset flowers.png
└── widgets
    ├── AppCard.qml
    ├── ChangeTitle.js
    ├── MenuOption.qml
    ├── MessageBox.qml
    ├── NotificationPanel.qml
    ├── TextFieldIcon.qml
    ├── TextInputField.qml
    └── Topbar.qml

10 directories, 60 files

Here is the content in QML file:

<RCC>
    <qresource prefix="/Icons">
        <file>icons/back-arrow-64.png</file>
        <file>icons/battery-icon.png</file>
        <file>icons/cart.png</file>
        <file>icons/cart-solo.png</file>
        <file>icons/close.png</file>
        <file>icons/devices.png</file>
        <file>icons/error.png</file>
        <file>icons/icons8-devices-32.png</file>
        <file>icons/info.png</file>
        <file>icons/menu.png</file>
        <file>icons/microphone-icon.png</file>
        <file>icons/notification.png</file>
        <file>icons/notification-icon.png</file>
        <file>icons/power-icon.png</file>
        <file>icons/restart.png</file>
        <file>icons/search.png</file>
        <file>icons/settings.png</file>
        <file>icons/settings-icon - app.png</file>
        <file>icons/shutdown.png</file>
        <file>icons/shutdown-menu.png</file>
        <file>icons/star.png</file>
        <file>icons/success.png</file>
        <file>icons/user-icon.png</file>
        <file>icons/warning.png</file>
        <file>icons/account.png</file>
        <file>icons/monitor.png</file>
    </qresource>
    <qresource prefix="/screens">
        <file>screens/AppMenu.qml</file>
        <file>screens/Desktop.qml</file>
        <file>screens/Login.qml</file>
    </qresource>
    <qresource prefix="/Wallpapers">
        <file>wallpapers/cubes.jpg</file>
        <file>wallpapers/sunset flowers.png</file>
    </qresource>
</RCC>

Please help me out. It will highly appreciated.

Thank you

Raghav
  • 33
  • 1
  • 8
  • Probably the path to the icon is wrong. Is there any output when running the application? Could you share your qrc and a tree of your project? – iam_peter Mar 16 '23 at 10:17
  • Hi, I have written the project tree in the answer itself. – Raghav Mar 16 '23 at 11:11
  • What about the content of the qrc file? – iam_peter Mar 16 '23 at 11:21
  • Sorry, Posting it now – Raghav Mar 16 '23 at 11:51
  • With qrc content I've meant the source not screenshots. I've added the pyqt tag as it is a python based project. – iam_peter Mar 16 '23 at 12:31
  • Sorry, I am beginner. I am updating it in the answer only. – Raghav Mar 16 '23 at 12:44
  • 1
    Are you importing the generated `rc_resources.py` in your main file like so `import rc_resources`? Have a look at the [documentation](https://doc.qt.io/qtforpython/tutorials/basictutorial/qrcfiles.html#generating-a-python-file) and [this](https://stackoverflow.com/questions/69311344/how-to-use-qrc-files-in-qml-files) SO question. – iam_peter Mar 16 '23 at 13:17
  • Thanks it worked please post this as an answer so that I can upvote it – Raghav Mar 18 '23 at 04:04

2 Answers2

2

You need to import the generated rc_resources.py in your main file like

import rc_resources

Have a look at the documentation and this SO question.

iam_peter
  • 3,205
  • 1
  • 19
  • 31
1

Please, please, do not name your source file as "Component.qml". This has the potential of clashing with the Qt's Component class which can cause major problems.

For the Rectangle component inside your RowLayout, I recommend that you do not use width and height. Instead, use Layout.preferredWidth and Layout.preferredHeight.

After playing around with your component, I believe your component looks very similar to the built-in Menu component. Here's a demo where you can compare your component with the standard one:

import QtQuick
import QtQuick.Controls
Page {
    Column {
        MenuOption {
            btnText: "btnText"
            btnColor: "steelblue"
            btnIconWidth: 32
            btnIconHeight: 32
            btnIcon: "sample.svg" 
        }
        MenuItem {
            width: 300
            height: 50
            text: "btnText"
            background: Rectangle { color: "steelblue" }
            icon.width: 32
            icon.height: 32
            icon.source: "sample.svg"
            palette.windowText: "white"
            icon.color: "black"
        }
    }
}

// MenuOption.qml
import QtQuick
import QtQuick.Layouts

Item {
    property alias option_width: menu_option_btn.width
    property alias btnText: btn_text.text
    property alias btnIcon: btn_icon.source
    property alias btnColor: bg_option.color
    property alias btnIconWidth: btn_icon.sourceSize.width
    property alias btnIconHeight: btn_icon.sourceSize.height
    
    id: menu_option_btn
    height: 50
    width: 300
    
    Rectangle {
        id: bg_option
        color: "#433f3f"
        anchors.fill: parent
    }
    
    MouseArea {
        id: mouseArea
        anchors.fill: parent
        
        RowLayout {
            id: btn_layout
            anchors.fill: parent
            
            Rectangle {
                id: image_holder
                width: 50
                height: 200
                color: "#0000ffff"
                Layout.maximumWidth: 50
                Layout.minimumWidth: 50
                Layout.fillHeight: true
                
                Image {
                    id: btn_icon
                    anchors.fill: parent
                    sourceSize.height: 52
                    sourceSize.width: 52
                    anchors.leftMargin: 2
                    anchors.bottomMargin: 5
                    anchors.topMargin: 5
                    fillMode: Image.PreserveAspectFit
                    visible: true
                    cache: false
                }
            }
            
            Text {
                id: btn_text
                color: "#ffffff"
                text: qsTr("Text")
                font.pixelSize: 16
                Layout.leftMargin: 5
                Layout.fillWidth: true
            }
        }
    }
}

// sample.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<path
stroke="black"
fill="none"
d="M 4 4 l 1 0
M 10 4 l 1 0
M 5 5 l 1 0
M 9 5 l 1 0
M 4 6 l 7 0
M 3 7 l 2 0
M 6 7 l 3 0
M 10 7 l 2 0
M 2 8 l 11 0
M 2 9 l 1 0
M 4 9 l 7 0
M 12 9 l 1 0
M 2 10 l 1 0
M 4 10 l 1 0
M 10 10 l 1 0
M 12 10 l 1 0
M 5 11 l 2 0
M 8 11 l 2 0"
/>
</svg>

You can Try it Online!

Stephen Quan
  • 21,481
  • 4
  • 88
  • 75
  • I have not named the file "Component.qml" it was an example the actual name is "MenuOption.qml" – Raghav Mar 18 '23 at 03:41