qml创建无边框带阴影的模态窗口

qml创建Window主要是以下两种做法:

  1. 使用QQmlApplicationEngine加载qml文件,qml中顶层元素必须为Window或ApplicationWindow;
  2. 使用QQuickView加载qml文件,qml中顶层元素不能为Window/ApplicationWindow,因为QQuickView继承于QQuickWindow,本身就是一个Window;

实现效果如下图所示:

 

1. 加载qml代码

// QQmlApplicationEngine
#include <QQmlApplicationEngine>

QQmlApplicationEngine *engine = new QQmlApplicationEngine();
engine->load(QUrl(QStringLiteral("qrc:/main.qml")));


// QQuickView
#include <QQmlContext>
#include <QQuickView>

QQuickView *viwer = new QQuickView();
viwer->setSource(QUrl("qrc:/main.qml"));
viwer->rootContext()->setContextProperty("mainwindow", viwer);
viwer->show();

 

2. 设置无边框

// QQuickView
QQuickView viewer = new QQuickViewer();
viewer->setFlags(Qt::FramelessWindowHint);


// QQmlApplicationEngine
ApplicationWindow {
	// 其余代码省略
    flags: Qt.FramelessWindowHint
}

 

3. 设置模态

// QQuickView
QQuickView *viewer = new QQuickView();
viewer->setFlags(Qt::FramelessWindowHint);
viewer->setModality(Qt::ApplicationModal);


// QQmlApplicationEngine
ApplicationWindow {
    // 其余代码省略
    flags: Qt.FramelessWindowHint
    modality: Qt.ApplicationModal
}

 

4. 设置边缘阴影

在设置无边框属性时,系统会使窗口会失去标题栏和边缘阴影效果,在QWidget中亦是如此,因此需要手动加上边缘阴影效果及标题栏中的关闭按钮等。在QML中,阴影的实现主要是DropShadow。

import QtGraphicalEffects 1.12    // for DropShadow

ApplicationWindow {
    id: mainWindow
    visible: true
    width: 1050
    height: 689
    color: "#00000000"
    // 如果不加上Qt.Window,则程序不会依附在任务栏
    flags: Qt.FramelessWindowHint | Qt.Window
    modality: Qt.ApplicationModal
    
    // 其余省略代码...
	
	Rectangle {	// 用以放置窗口中的所有内容
           id: mainRec
           width: parent.width-20
           height: parent.height-20
           anchors.centerIn: parent
           
           // 其余省略代码...
    }
	
	// 左边缘及上边缘阴影
    DropShadow {
           anchors.fill: mainRec
           horizontalOffset: -5
           verticalOffset: -5
           radius: 12.0
           samples: 25
           color: "#20000000"
           spread: 0.0
           source: mainRec
	}
	
	// 右边缘及下边缘阴影
	DropShadow {
			anchors.fill: mainRec
			horizontalOffset: 5
			verticalOffset: 5
			radius: 12.0
			samples: 25
			color: "#20000000"
			spread: 0.0
			source: mainRec
	}
}

 

5. 关闭按钮

import QtQuick.Controls 2.0

Button {
   id: closeBtn
   width: 25
   height: 25
   anchors.right: parent.right
   anchors.rightMargin: 5
   anchors.top: parent.top
   anchors.topMargin: 5
   palette {
	   button: "transparent"
   }

   Image {

	   width: 25
	   height: 25
	   fillMode: Image.PreserveAspectFit
	   source: "qrc:/close.png"
   }

   MouseArea {
	   anchors.fill: parent
	   onClicked: {
		   mainWindow.close()
	   }
   }
}

 

 

以QQmlApplicationEngine为例,总的实现代码如下:

main.qml

import QtQuick 2.0
import QtQuick.Controls 2.0
import QtQuick.Window 2.0
import QtGraphicalEffects 1.12


ApplicationWindow {
    id: mainWindow
    visible: true
    width: 1050
    height: 689
    color: "#00000000"
    flags: Qt.FramelessWindowHint
    modality: Qt.ApplicationModal

    MouseArea {
        x: 10
        y: 10
        height: 50
        width: parent.width-20
        acceptedButtons: Qt.LeftButton
        property point clickPos: "0,0"
        onPressed: {
             clickPos  = Qt.point(mouse.x,mouse.y)
        }
        onPositionChanged: {
            var delta = Qt.point(mouse.x-clickPos.x, mouse.y-clickPos.y)
            mainWindow.setX(mainWindow.x+delta.x)
            mainWindow.setY(mainWindow.y+delta.y)
        }
    }

    Rectangle {
           id: mainRec
           width: parent.width-20
           height: parent.height-20
           anchors.centerIn: parent

           Text {
               id: name
               anchors.top: parent.top
               anchors.topMargin: 100
               anchors.left: parent.left
               anchors.leftMargin: 100
               text: testData.getCurrentDateTime()
           }

           Button {
               id: closeBtn
               width: 25
               height: 25
               anchors.right: parent.right
               anchors.rightMargin: 5
               anchors.top: parent.top
               anchors.topMargin: 5
               palette {
                   button: "transparent"
               }

               Image {

                   width: 25
                   height: 25
                   fillMode: Image.PreserveAspectFit
                   source: "qrc:/close.png"
               }

               MouseArea {
                   anchors.fill: parent
                   onClicked: {
                       mainWindow.close()
                   }
               }
          }
    }

    // 左边缘及上边缘阴影
    DropShadow {
           anchors.fill: mainRec
           horizontalOffset: -5
           verticalOffset: -5
           radius: 12.0
           samples: 25
           color: "#20000000"
           spread: 0.0
           source: mainRec
    }

    // 右边缘及下边缘阴影
    DropShadow {
            anchors.fill: mainRec
            horizontalOffset: 5
            verticalOffset: 5
            radius: 12.0
            samples: 25
            color: "#20000000"
            spread: 0.0
            source: mainRec
    }

}

 

QtTest.cpp

#include "widget.h"
#include "ui_widget.h"

#include <QQmlContext>
#include <QQmlApplicationEngine>
#include <QQuickView>
#include <QGuiApplication>


Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 点击界面上的按钮打开此qml窗口
    connect(ui->pushButton, &QPushButton::clicked, this, [=]()
    {
        QQmlApplicationEngine *engine = new QQmlApplicationEngine();
        engine->load(QUrl(QStringLiteral("qrc:/main.qml")));
    });
}

Widget::~Widget()
{
    delete ui;
}

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值