Customizing Window with PathSvg
Asked Answered
C

1

0

Here's what I've now in my main.qml:

import QtQuick 2.9
import QtQuick.Window 2.3
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.5
import QtQuick.Shapes 1.12
import QtGraphicalEffects 1.0

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Test Window")

    property double iconSize: 24

    RowLayout{
        anchors.fill: parent
        Rectangle{
            id: rect
            Layout.fillHeight: true
            Layout.preferredWidth: iconSize
            ListView{
                id: lv
                model: ViewModel.views
                anchors.fill: parent
                delegate: ItemDelegate{
                    width: iconSize
                    height: iconSize
                    ColumnLayout{
                        Shape {
                            ShapePath {
                                fillColor: hovered? "blue" : highlighted? "green" : "black"
                                PathSvg { path: modelData.icon }
                            }
                        }
                    }
                    onClicked: {
                        lv.currentIndex = index
                        load.setSource(modelData.view)
                    }
                    highlighted: ListView.isCurrentItem
                    background: Rectangle{
                        anchors.fill: parent
                        color: "transparent"
                    }
                }
                Component.onCompleted: load.setSource("a.qml")
            }
        }

        Loader{
            id: load
            Layout.fillHeight: true
            Layout.fillWidth: true
            Layout.margins: 5
        }

        DropShadow{
            anchors.fill: rect
            source: rect
            radius: 10
            samples: 15
            color: "black"
        }

        DropShadow{
            anchors.fill: load
            source: load
            radius: 10
            samples: 15
            color: "black"
        }
    }
}

I get these warnings/error when I run the application:

qrc:/main.qml:58:9: QML DropShadow: Detected anchors on an item that is managed by a layout. This is undefined behavior; use Layout.alignment instead.
qrc:/main.qml:66:9: QML DropShadow: Detected anchors on an item that is managed by a layout. This is undefined behavior; use Layout.alignment instead. 

I've to have anchors.fill: elementId in both DropShadow to make it work, right? Here's how it looks:

enter image description here

First, those SVG aren't smooth, I've tried with some properties listed here BUT those actually don't help! What do I've to do to make those look better?

Second, I want to replace the default Window Title Bar with another Rectangle on top with DropShadow and add 3 more SVG as minimize, maximize and close buttons BUT haven't yet found any example of customizing default QtQuick Window.

EDIT

Here's Constants.h that holds SVG Path Data:

#ifndef CONSTANTS_H
#define CONSTANTS_H
#include<QString>

const QString AIcon = "M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M11,7A2,2 0 0,0 9,9V17H11V13H13V17H15V9A2,2 0 0,0 13,7H11M11,9H13V11H11V9Z";
const QString BIcon = "M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M15,10.5V9A2,2 0 0,0 13,7H9V17H13A2,2 0 0,0 15,15V13.5C15,12.7 14.3,12 13.5,12C14.3,12 15,11.3 15,10.5M13,15H11V13H13V15M13,11H11V9H13V11Z";
const QString CIcon = "M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M11,7A2,2 0 0,0 9,9V15A2,2 0 0,0 11,17H13A2,2 0 0,0 15,15V14H13V15H11V9H13V10H15V9A2,2 0 0,0 13,7H11Z";

#endif // CONSTANTS_H

here's View.h, the model:

#ifndef VIEW_H
#define VIEW_H

#include <QObject>
#include <QString>
#include "Property.h"

class View : public QObject
{
    Q_OBJECT
    PROPERTY(QString, icon)
    PROPERTY(QString, view)
public:
    View(QString icon, QString view) : m_icon(icon), m_view(view) {}
};

#endif // VIEW_H

here's VM.h, the ViewModel

#ifndef VM_H
#define VM_H

#include <QObject>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QtCore>
#include "Property.h"
#include "Constants.h"
#include "view.h"

class VM : public QObject
{
    Q_OBJECT
    PROPERTY(QVector<View*>, views)
public:
    explicit VM(QObject *parent = nullptr);

private:
    QQmlApplicationEngine engine;

};

#endif // VM_H

here's VM.cpp:

#include "vm.h"

VM::VM(QObject *parent) : QObject(parent)
{
    engine.rootContext()->setContextProperty("ViewModel", this);
    engine.load("qrc:/main.qml");

    m_views.push_back(new View(AIcon, "a.qml"));
    m_views.push_back(new View(BIcon, "b.qml"));
    m_views.push_back(new View(CIcon, "c.qml"));
    emit viewsChanged();
}

here's main.cpp:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "vm.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);
    VM vm;
    return app.exec();
}

the PROPERTY macro:

#ifndef PROPERTY_H
#define PROPERTY_H

#define PROPERTY(QType, name) \
    Q_PROPERTY(QType name READ name WRITE set##name NOTIFY name##Changed) \
    public: \
    QType name(){return m_##name;}\
    void set##name(QType value){m_##name = value; emit name##Changed();} \
    Q_SIGNAL void name##Changed(); \
    private: \
    QType m_##name;


#endif // PROPERTY_H

and here's a.qml:

import QtQuick 2.0

Item {
    anchors.fill: parent
    Rectangle{
        anchors.fill: parent
        Text{
            text: "A View"
            font.pointSize: 18
            anchors.centerIn: parent
        }
    }
}

a.qml, b.qml and c.qml are same except the text. For b.qml and I've B View as text and C View for c.qml

Claytonclaytonia answered 1/7, 2020 at 15:22 Comment(0)
C
0

Both flags: Qt.Window | Qt.CustomizeWindowHint and flags: Qt.FramelessWindowHint works. With the first I get a resize grip by default and a outer black border but the TitleBar gets taller than what I expect:

enter image description here

It always is shown in my Taskbar. With the latter it's perfect:

enter image description here

no outer border, no resize capability by default and it doesn't even appear in Taskbar. In both cases I've to handle the dragging manually!

Claytonclaytonia answered 1/7, 2020 at 18:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.